一点一滴

97 阅读1分钟

Ref

1,

在react中,每个组件都有ref属性。//指的是非函数式组件
在早先的用法中
添加ref属性,要添加一个回调函数。
ref的这个回调函数会在组件挂载的时候和卸载掉时候自动执行。
在普通的html元素中,该回调函数接受的形参就是该html元素本身(当组件卸载时,该形参就是null了)。如: <input ref={(input)=>{bulabula...}}>

2,

现在的用法中,class组件

利用的是React.createRef()方法,不再需要回调。 以点击button,聚焦input为例。

class CustomTextInput extends React.Component {
    constructor(props) {
      super(props);
    }
    inputRef = React.createRef(); //看这里
    onClick = () => { //看这里
        this.inputRef.current.focus()
    }

    render() {

      return (
        <div>
          <input
            type="text"
            ref={this.inputRef}/>  {/* 看这里 */}
          <input
            type="button"
            value="点击聚焦"
            onClick={this.onClick}// 看这里
          />
        </div>
      );
    }
  }

3,

函数式组件,使用的是useRef

const CustomTextInput2 = (props) => {
    const inputRef = useRef(); //看这里
    // const inputRef = React.createRef(); //看这里,creactRef也可以,但从性能上还是用useRef这个hook
    const onClick = () => { //看这里
        inputRef.current.focus();
    }
    return (
        <div>
          <input
            type="text"
            ref={inputRef}/>  {/* 看这里 */}
          <input
            type="button"
            value="点击聚焦"
            onClick={onClick}// 看这里
          />
        </div>
    )
}

在父组件中,如果自组件是函数组件,不能直接给ref属性 报错信息: Function components cannot be given refs. 要用ForwardRef把自组件包起来。

const CustomTextInput2 = forwardRef((props, inputRef) => { //看这里
    // const inputRef = useRef();  // 删除掉
    const onClick = () => { 
        inputRef.current.focus();
    }
    return (
        <div>
          <input
            type="text"
            ref={inputRef}/> 
          <input
            type="button"
            value="点击聚焦"
            onClick={onClick}
          />
        </div>
    )
})

此时在父组件里拿到的ref直接是子组件里的input标签,而不是子组件本身了。
在父组件的onClick函数里,不需要再: inputRef.current.onClick();这样来调用子组件的onClcik()
直接: inputRef.current.focus();直接调用子组件input标签的focus()