React学习使用应注意的点(Refs)

refs

  1. React v16.3后创建ref及使用可通过以下方式(注:不能在函数式组件上使用 ref 属性,因为它们没有实例)
class RefComponent extends React.Component {
  render () {
    return <div></div>
  }
}  

let myRef = React.createRef() // 通过React.createRef()方法创建ref
const handleClick = () => {
	console.log(myRef.current) // 通过ref的current属性获取对应的组件或元素的实例
}

const Hello = (props) =>(
  <>
	  <div onClick={handleClick}>0.0</div>
	  <RefComponent ref={myRef} > // 通过ref={MyRef}将组件或元素实例赋予ref
	  </RefComponent>
  </>
)
  1. 可通过回调函数的方式去暴露子元素的ref
官网例子:
function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />
    </div>
  );
}

class Parent extends React.Component {
  render() {
    return (
      <CustomTextInput
        inputRef={el => this.inputElement = el}
      />
    );
  }
}
  1. 假设我们现在有一个高阶组件ComponentA和利用这个ComponentA生成的一个ComponentB,当我们想尝试拿到ComponentB的实例时,如果我们直接给ComponentB加上之前提到的创建添加ref的方法,那么这里就会出现一个问题,最终我们获取到的实例是ComponentA的实例,而不是我们所需要的ComponentB的实例
const ContainerRef = (Component) => {
  class Container extends React.Component {
    render () {
      return (
        <div>
          <Component {...this.props}/>
        </div>
      )
    }
  }
  return Container
}

const Ref = (props) => <div>This is child</div>

const RefComponent = ContainerRef(Ref)

let myRef = React.createRef()
const handleClick = () => {
	console.log(myRef)
}

const Hello = (props) =>(
  <>
	  <button onClick={handleClick}>Test</button>
	  <RefComponent ref={myRef} > // 为myRef绑上ref实例
	  </RefComponent>
  </>
)

效果如下,打印的ref实例是高阶组件的实例
效果图1
为了解决这个问题,React为我们提供了一个React.forwardRef()方法,首先我们来看一下官方文档对这个方法的说明,“React.forwardRef accepts a render function that receives props and ref parameters and returns a React node”,这里只说了forwardRef接受一个有两个参数(props, ref)的render函数,没有它的具体原理,让我们先尝试官网的用法,结合下面的代码再来一探究竟

const ContainerRef = (Component) => {
  class Container extends React.Component {
    render () {
    // 这里从props中获取出来forwardRef作为子组件的ref
      const {forwardRef, ...rest} = this.props
       return (
        <div>
          <Component {...rest} ref={forwardRef}/>
        </div>)
    }
  }
	// 传入上面提到的方法,forwardRef是React底层调用时传入的Ref,也是我们平常无法直接拿到的ref
	// 一起放入props中,使Container可以从props中取出,传递给子组件
  return React.forwardRef((props, forwardRef) => {
    return (<Container {...props} forwardRef={forwardRef}/>)
  })
}

class Ref extends React.Component {
  render () {
    return <div>This is child</div>
  }
}

const RefComponent = ContainerRef(Ref)

let myRef = React.createRef()
const handleClick = () => {
//这里我们输出了上面React.forwardRef()返回的结果,是这样子的
// {$$typeof: Symbol(react.forward_ref), render: ƒ},得知React.forwardRef返回的是另一种React结点的实例,它类似于组件结点,但只有render方法,它的render函数就是我们传入的方法
  console.log(RefComponent)
}

const Hello = (props) =>(
  <>
	  <button onClick={handleClick}>Test</button>
	  <RefComponent ref={myRef} >
	  </RefComponent>
  </>
  )

总结:React.forwardRef方法返回一个类型为react.forward_ref的React结点实例,将我们传入的函数作为其实例的render方法,而该render方法被调用时,被传入其props和ref供我们使用,即可用来解决一个组件需要获取父组件赋予的ref的值。

React 中结合 TypeScript 使用 Refs 可以通过 `React.RefObject` 接口来定义 Ref 类型,具体步骤如下: 1. 首先,在组件中定义一个 Ref 对象: ```typescript import React, { useRef } from 'react'; interface MyComponentProps { // props } const MyComponent: React.FC<MyComponentProps> = (props) => { const inputRef = useRef<HTMLInputElement>(null); // ... }; ``` 这里我们定义了一个名为 `inputRef` 的 Ref 对象,它的类型是 `React.RefObject<HTMLInputElement>`,指向一个 input 元素。 2. 将 Ref 对象传递给组件中的元素或组件: ```typescript return ( <div> <input type="text" ref={inputRef} /> </div> ); ``` 这里我们将 `inputRef` 传递给了 input 元素的 `ref` 属性,这样在组件渲染完毕后,我们就可以通过 `inputRef.current` 来访问这个 input 元素了。 3. 在组件中使用 Ref 对象: ```typescript const handleClick = () => { if (inputRef.current) { inputRef.current.focus(); } } return ( <div> <input type="text" ref={inputRef} /> <button onClick={handleClick}>Focus</button> </div> ); ``` 这里我们定义了一个 `handleClick` 方法,当用户击按钮时,调用这个方法,它会将焦聚焦到 input 元素上。通过 `inputRef.current` 可以获取当前 input 元素的引用,然后调用 `focus()` 方法即可聚焦。 以上就是在 React 中结合 TypeScript 使用 Refs 的基本步骤。需要注意的是,当使用 Refs 时,要确保对 Ref 对象的访问是安全的,即先检查 `ref.current` 是否为 null,然后再进行操作,以避免出现运行时错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值