在Reaction中从父组件调用子组件的方法是反模式的吗?为什么?
我正在尝试实现一个特定的Wizard
组件,用户可以使用下面的模式使用该组件。
<Wizard {...wizardProps} onFinish={this.handleFinish}>
<WizardStep onValidate={() => this.componentARef.isValid()}>
<ComponentA onRef = { ref => (this.componentARef = ref)}/>
</WizardStep>
<WizardStep onValidate={() => this.componentBRef.isValid()}>
<ComponentB onRef = { ref => (this.componentBRef = ref)}/>
</WizardStep>
<WizardStep onValidate={() => this.componentCRef.isValid()}>
<ComponentC onRef = { ref => (this.componentCRef = ref)}/>
</WizardStep>
</Wizard>
现在考虑反应方式,我们不能/不应该从父组件调用子组件的方法。在这里,我想在每个组件中保留一个isValid
方法,它将在单击Next/Finish
按钮时从父Wizard
组件调用。反应方式建议将状态和逻辑转移到父组件。但那样的话,我将无法在任何其他向导或任何其他位置重用相同的组件,例如ComponentA
,否则我将不得不在使用ComponentA
的每个父组件中复制验证逻辑。使用ref
或this approach,我可以轻松访问子组件的方法(isValid
)。
截至今天(Reaction版本16.6),我没有看到在Reaction中根据需要使用此模式的任何缺陷。在Reaction中使用此模式可能会遇到什么问题?在这个特定的示例中,有没有更好的选项,可以使用它将isValid
方法保留在步骤组件(例如ComponentA
)中以供重用?
解决方案
简明答案
是。
详细回答
发件人React's doc on refs:
在典型的Reaction数据流中,道具是父组件与其子组件交互的唯一方式。若要修改子对象,请使用新道具重新渲染它。
您的第一个倾向可能是在您的应用程序中使用Ref来"使事情发生"。如果是这样的话,花点时间仔细考虑一下状态应该在组件层次结构中的什么位置拥有。
创建引用是为了在特定用例(焦点、文本选择、媒体播放、第三方库等)中访问DOM,但在尝试使其他组件执行操作时应避免使用这些引用。
所以你当然可以有一个在使用ref调用子组件方法的同时工作的Reaction应用程序,但它是非常反模式的。
相关文章