Javascript 从多个复杂子组件获取值的最佳方法?
我有一个父组件,它有一个名为script的基本数据,它有多个序列,每个序列由多个项目组成(输入、下拉等等) 现在,我需要在parent中更新数据,因为我想放置一个保存按钮,只需单击一下即可保存所有表单 它看起来像这样:Javascript 从多个复杂子组件获取值的最佳方法?,javascript,reactjs,Javascript,Reactjs,我有一个父组件,它有一个名为script的基本数据,它有多个序列,每个序列由多个项目组成(输入、下拉等等) 现在,我需要在parent中更新数据,因为我想放置一个保存按钮,只需单击一下即可保存所有表单 它看起来像这样: class Wrapper Component extends React.Component { constructor(props) { super(props); this.state = { formsData: {}, };
class Wrapper Component extends React.Component {
constructor(props) {
super(props);
this.state = {
formsData: {},
};
}
}
我尝试了两种处理方法:
- 每个孩子都有一个onChange属性 其中父级使用新数据设置状态。但问题是 这里是,因为这是一个相当复杂的形式,它重新呈现 每一次都是如此,所以输入时有明显的延迟 投入
- 在孩子身上改变道具对象的“坏”, 这很快,但我知道这是一个糟糕的做法
在这样的规模上处理表单的最佳方式是什么?是否应进行不同的设置?提升状态确实是正确的方法。要优化子节,可以使用
- PureComponent==>
- AKA记忆组件==>
React.memo是一个高阶组件。它类似于React.PureComponent,但用于函数组件而不是类 另外,如果您在付款范围内
- useCallback:
- 使用备忘录:
- 重新选择:
将所有表单包装在一个只处理保存所有表单数据和运行“全部保存”功能的组件中: 包装器组件应该有一个包含所有表单数据的状态,它可能看起来像这样:
class Wrapper Component extends React.Component {
constructor(props) {
super(props);
this.state = {
formsData: {},
};
}
}
formsData的结构应该大致如下:
{0:{标题:“文本”,键入:“视频”,等等:“等等”},
1:{标题:“文本”,类型:“视频”,等:“等”}
键(0、1等)表示表单id,可以为每个has设置任何唯一的修改器
然后让包装器组件处理每个表单的onChange->每个表单上的每个更改都应该提升新状态(新更新的数据),并相应地更新formsData状态obj:
const onChange(formData) {
const formattedData = {[formData.id]: {...formData}}
this.setState({formsData: {...formsData, ...formattedData}})
}
*这只是一个例子,在每个表单中的每次更改中,您都可以提升整个数据对象,您可以通过多种方式来实现
此外,还应该在包装器组件中处理saveall按钮,并将与它一起存储的所有数据提升到父组件/处理它本身中的相关函数
祝你好运 这是一个我花了一些时间与自己斗争的问题。有多种方法可以在更高级别上维护子状态;然而,我发现在您的特定情况下,最好使用Redux 明确地说,我通常不惜一切代价避免Redux(有利于React的上下文),但Redux使您能够订阅子组件中的特定状态。当您只需要一个子组件进行更新时,侦听子组件中的一个状态将阻止父组件和同级组件进行更新。当一次处理多个表单时,这将更加高效 例如,以下组件将只侦听影响其自身状态的状态更新。这些更新将绕过表单父级和同级组件:
import React from 'react';
import { connect } from 'react-redux';
import * as actions from 'redux/actions';
// Custom component
import { InputField } from 'shared';
const FormOne = ({ me, actions }) => (
<form>
<InputField
inputId="f1f1"
label="field one"
value={me.fieldOne}
onChange={(e) => actions.setFormOneFieldOne(e.target.value)}
/>
<InputField
inputId="f1f2"
label="field two"
value={me.fieldTwo}
onChange={(e) => actions.setFormOneFieldTwo(e.target.value)}
/>
<InputField
inputId="f1f3"
label="field three"
value={me.fieldThree}
onChange={(e) => actions.setFormOneFieldThree(e.target.value)}
/>
</form>
);
export default connect(state => ({ me: state.formOne }), actions)(FormOne);
import React, { useContext } from 'react';
// Custom component
import { InputField } from 'shared';
// Custom context - below component must be wrapped with the provider
import { FormContext } from 'context';
const FormTwo = () => {
const context = useContext(FormContext);
return(
<form>
<InputField
inputId="f2f1"
label="field one"
value={context.state.formTwo.fieldOne}
onChange={(e) => context.setFormTwoFieldOne(e.target.value)}
/>
<InputField
inputId="f2f2"
label="field two"
value={context.state.formTwo.fieldTwo}
onChange={(e) => context.setFormTwoFieldTwo(e.target.value)}
/>
<InputField
inputId="f2f3"
label="field three"
value={context.state.formTwo.fieldThree}
onChange={(e) => context.setFormTwoFieldThree(e.target.value)}
/>
</form>
);
};
export default FormTwo;
可以对上述两个组件进行一些改进,但它们旨在作为如何将子组件连接到提升状态的示例。也可以使用道具
连接到单个父组件,但这是可能的效率最低的选项,并且会扰乱您的体系结构
关键外卖:针对您的用例使用Redux。如果正确实施,这是最有效的选择
祝你好运 谢谢,PureComponent和memorized Component有什么区别,它们的功能基本相同,性能也一样吗?或者我应该使用一个而不是另一个?React.memo是一个更高阶的组件。它类似于React.PureComponent,但用于函数组件而不是类。谢谢!为了简单起见,我试图避免Redux,但我想这最终会变得很难。您认为使用PureComponent可以有效地解决这个问题,还是redux会更好?
React.PureComponent
或React.memo
在某些情况下是不错的选择,但我会在您的应用中避免它们,原因有两个:1。通常,挂钩是React的前进方向,因此React.PureComponent
限制了您的架构。2.您的用例相当复杂,随着它的扩展,您需要提升您的状态以保持干净的体系结构。这方面的两个主要选项是Redux和context。在这种情况下,Redux将更具性能。这里要明确的是,即使您决定使用Redux,您仍然可以使用React.memo
来实现功能组件。如果一切都设置正确的话,它可能不会给你带来多大的性能提升。我想了想,redux是一个不错的选择。我应该只在复杂的事情上使用redux状态,在使用简单组件时仍然使用普通状态,对吗?是的,功能组件和挂钩是首选的。类组件仍然有几个用例,但它们非常罕见。你会知道如果你遇到一个。