Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 调用子组件'是反模式的吗;在react中来自父级的s方法以及原因?_Javascript_Reactjs_Reactive Programming - Fatal编程技术网

Javascript 调用子组件'是反模式的吗;在react中来自父级的s方法以及原因?

Javascript 调用子组件'是反模式的吗;在react中来自父级的s方法以及原因?,javascript,reactjs,reactive-programming,Javascript,Reactjs,Reactive Programming,我正在尝试实现一个特定的向导组件,用户可以使用下面的模式使用该组件 <Wizard {...wizardProps} onFinish={this.handleFinish}> <WizardStep onValidate={() => this.componentARef.isValid()}> <ComponentA onRef = { ref => (this.componentARef = ref)}/> &

我正在尝试实现一个特定的
向导
组件,用户可以使用下面的模式使用该组件

<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>

this.componentARef.isValid()}>
(this.componentARef=ref)}/>
this.componentBRef.isValid()}>
(this.componentBRef=ref)}/>
this.componentCRef.isValid()}>
(this.componentCRef=ref)}/>
现在考虑一下我们不能/不应该从父组件调用子组件的方法的反应方式。在这里,我想在每个组件中保留一个
isValid
方法,单击
Next/Finish
按钮将从父
Wizard
组件调用该方法。反应方式建议将状态和逻辑移动到父组件。但这样我就无法在任何其他向导或任何其他地方重用相同的组件,例如,
ComponentA
,否则我将不得不在使用
ComponentA
的每个父组件中复制验证逻辑。使用
ref
或我可以轻松访问子组件的方法(
isValid

到今天为止(React版本16.6),我在React中没有看到使用这种基于需要的模式的任何陷阱。在react中使用此模式可能会遇到什么问题?在这个特定的示例中,有没有更好的选项,我可以使用它在步骤组件(例如,
ComponentA
)中保留
isValid
方法以供重用

简短回答 对

长话短说 发件人:

在典型的React数据流中,道具是父组件与其子组件交互的唯一方式。要修改子对象,请使用新道具重新渲染它

您的第一个倾向可能是在应用程序中使用refs来“使事情发生”。如果是这种情况,请花一点时间,更批判性地思考在组件层次结构中应该在哪里拥有状态

创建REF是为了在特定用例(焦点、文本选择、媒体播放、第三方LIB等)中访问DOM,但在尝试让其他组件执行操作时应避免使用REF


当然,您可以使用React应用程序在使用refs调用子组件方法时工作,但是是的,它非常反模式。

简短回答:在您的场景中,这种方法是可以的。当您的情景发生变化时,只需重新访问它。

说明

在你的场景中,这不是一个反模式。如果您通过Ro.

控制子组件的行为,它将被认为是一种反模式。 React建议避免像general建议的那样的反模式,避免边缘情况,即组件由于受到不同真相来源的控制而变得不稳定。但是,在像您这样的场景中,您可以确定为什么要使用它,这很好


例如,React建议不要从道具填充状态。这是正确的,因为这样您就有两个真相来源,您需要同步它们,否则您的组件将无法正常工作。但是,如果您确信,您的道具(特别是数据)不会改变,它不再是一种反模式,因为您现在正在从道具中播种状态,但它将继续仅在状态级别进行管理。

技术上公认,您应该使用自上而下、解耦的方法来设计React中的组件和数据流,是的,考虑到这一点,在父对象中调用子方法是一种反模式。为什么不能将“下一步/完成”按钮变成一个可重用的组件,然后由每个组件使用?这样,每个组件都可以控制该按钮(即在必要时禁用它),并且您仍然可以保持整个向导表单流的完整性。是的,我理解考虑react范式这是不可取的。但就像在这个场景中,当我试图抽象出
ComponentA
的逻辑以及它的验证时,它似乎是非常明显和直接的。我只是想了解这个术语
反模式
是否有我以后可能遇到的缺点/陷阱。prev/next/finish按钮已经是一个可重用的
向导页脚
组件。但是我不想把它包含在我的stepComponent中(比如说
ComponentA
),因为这样我就无法在其他可能需要其他操作的地方使用该表单/组件,例如表单
submit
按钮。我已经阅读了这些确切的行,我总是遵循这种思想,在大多数情况下,我使用state而不是refs(例如受控部件)但是在这个场景中,一件重要的事情是我没有更新子组件,而是在读取状态或状态派生值,解决方案对我来说似乎很完美,即使它违反了react准则。在我的问题中,我最感兴趣的是给定示例的
为什么
部分和更好的解决方案(如果有的话)。