【发布时间】: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}
/>
}
}
此解决方案运行良好,但我已经看到 disagreement 的 lot 是否是最佳做法。 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