【问题标题】:Best practices for using React refs to call child function使用 React refs 调用子函数的最佳实践
【发布时间】:2017-07-14 14:55:54
【问题描述】:

我希望对使用 React refs 调用子函数有所了解。我有一个父组件,它是一个带有几个按钮的工具栏,在子组件中我可以访问库的导出功能。我想在父组件中单击按钮时调用此导出功能。目前我正在使用 React refs 来完成这个:

Parent.js [参考]

class Parent extends React.Component {

  onExportClick = () => {
    this.childRef.export();
  }

  render() {
    return (
      <div>
        <button onClick={this.onExportClick} />Export</button>
        <Child ref={(node) => this.childRef = node;} />
      </div>
    )
  }
}

Child.js [参考]

class Child extends React.Component {

  export() {
    this.api.exportData();
  }

  render() {
    <ExternalLibComponent
      api={(api) => this.api = api}
    />
  }
}

此解决方案运行良好,但我已经看到 disagreementlot 是否是最佳做法。 React 在 refs 上的官方 doc 说我们应该“避免将 refs 用于任何可以以声明方式完成的事情”。在discussion post 中针对类似问题,React 团队的 Ben Alpert 说“refs 正是为这个用例而设计的”,但通常你应该尝试通过向下传递一个 prop 来声明式地做到这一点。

如果没有ref,我会以声明方式执行此操作:

Parent.js [声明性]

class Parent extends React.Component {

  onExportClick = () => {
    // Set to trigger props change in child
    this.setState({
      shouldExport: true,
    });

    // Toggle back to false to ensure child doesn't keep 
    // calling export on subsequent props changes
    // ?? this doesn't seem right
    this.setState({
      shouldExport: false,
    });
  }

  render() {
    return (
      <div>
        <button onClick={this.onExportClick} />Export</button>
        <Child shouldExport={this.state.shouldExport}/>
      </div>
    )
  }
}

Child.js [声明性]

class Child extends React.Component {

  componentWillReceiveProps(nextProps) {
    if (nextProps.shouldExport) {
      this.export();
    }
  }

  export() {
    this.api.exportData();
  }

  render() {
    <ExternalLibComponent
      api={(api) => this.api = api}
    />
  }
}

虽然 refs 被视为解决此问题的“逃生舱”,但这种声明式解决方案似乎有点 hacky,而且并不比使用 refs 更好。我应该继续使用 refs 来解决这个问题吗?还是我应该采用有点 hacky 的声明性方法?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您无需将shouldExport 设置回false,而是可以检测到更改:

    componentWillReceiveProps(nextProps) {
        if (nextProps.shouldExport !== this.props.shouldExport) {
            this.export();
        }
    }
    

    那么shouldExport 的每一次切换都会导致一次导出。然而这看起来很奇怪,我会使用一个我会增加的数字:

    componentWillReceiveProps(nextProps) {
        if (nextProps.exportCount > this.props.exportCount) {
            this.export();
        }
    }
    

    【讨论】:

      【解决方案2】:

      我现在在很多场合都遇到过同样的问题,由于 React 团队不鼓励这样做,我将在以后的开发中使用 props 方法,但问题是有时你想向父级返回一个值组件,有时你需要检查孩子的状态来决定是否触发事件,因此 refs 方法将永远是我最后的避风港,我建议你也这样做

      【讨论】:

      • 谢谢。现在我很清楚答案是“视情况而定”。这不是非黑即白的情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      • 2012-08-13
      • 2017-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多