React ref 与 onRef 实现父组件修改子组件state方式对比

2,243 阅读2分钟

让我们回忆一下在组件中使用ref

// 我的实现方式
import React, { Component } from 'react';
export default class App extends React.Component {
  constructor(props) {
    super(props);
  }

  focusTextInput = () => {
    console.log(this.refs.textInput);//这边输出input的dom对象
    this.refs.textInput.focus();
  }

  render() {
    // 告诉 React 我们想把 <input> ref 关联到
    // 构造器里创建的 `textInput` 上
    return (
      <div>
        <input
          type="text"
          ref="textInput" />

        <input
          type="button"
          value="点击我获取焦点"
          onClick={this.focusTextInput}
        />
      </div>
    );
   }
 }
// 大佬的实现方式 
import React, { Component } from 'react';
export default class App extends React.Component {
 constructor(props) {
   super(props);
   // 创建一个 ref 来存储 textInput 的 DOM 元素
   this.textInput = React.createRef();
   this.focusTextInput = this.focusTextInput.bind(this);
 }

 focusTextInput() {
   // 直接使用原生 API 使 text 输入框获得焦点
   // 注意:我们通过 "current" 来访问 DOM 节点
   this.textInput.current.focus();
   console.log(this.textInput.current);//这边输出input的dom对象
 }

 render() {
   // 告诉 React 我们想把 <input> ref 关联到
   // 构造器里创建的 `textInput` 上
   return (
     <div>
       <input
         type="text"
         ref={this.textInput} />

       <input
         type="button"
         value="点击我获取焦点"
         onClick={this.focusTextInput}
       />
     </div>
   );
  }
}

我们先看ref实现父组件拿到子组件dom:

class Demo extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      num: 0,
    }
  }
  add = () => {
    this.setState({ num: this.state.num + 1 })
  }
  render() {
    return (<div>
      {this.state.num}
      <button onClick={this.add} ref={this.props.propRef}> 点我+1</button>
    </div>);
  }
}

export default class App extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个 ref 来存储 textInput 的 DOM 元素
    this.textInput = React.createRef();
  }

  focusTextInput = () => {
    // 直接使用原生 API 使 text 输入框获得焦点
    // 注意:我们通过 "current" 来访问 DOM 节点
    this.textInput.current.click();
  }
  render() {
    // 告诉 React 我们想把 <input> ref 关联到
    // 构造器里创建的 `textInput` 上
    return (
      <div>
        <Demo propRef={this.textInput} />
        <button onClick={this.focusTextInput}>点我也+1</button>
      </div>
    );
  }
}

再看onRef实现父组件拿到子组件dom:

class Demo extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      num: 0,
    }
  }
  componentDidMount() {
    this.props.propRef(this);
  }
  add = () => {
    this.setState({ num: this.state.num + 1 })
  }
  render() {
    return (<div>
      {this.state.num}
      <button onClick={this.add} ref="test"> 点我+1</button>
    </div>);
  }
}

export default class App extends React.Component {
  constructor(props) {
    super(props);
  }

  focusTextInput = () => {
    this.xxx.refs.test.click();
  }
  render() {
    return (
      <div>
        <Demo propRef={(item) => this.xxx = item}/>
        <button onClick={this.focusTextInput}>点我也+1</button><br/>
      </div>
    );
  }
}

小白人生第一次发文,略微简洁,还请大家谅解。