生孩子';在ReactJS中设置父级状态的默认道具

生孩子';在ReactJS中设置父级状态的默认道具,reactjs,Reactjs,与类似,但我只对将子组件的默认道具放入父组件感兴趣 那我为什么要这么做呢 我有一个父组件,它呈现包含HTML表单的子组件。父级的render()方法将其状态数据作为道具传递给子级,这是它应该做的 最初,子表单应该只包含一些默认数据。从子组件中定义的defaultProps获取数据是有意义的。毕竟,我不想在父级状态下设置默认数据的负载,仅仅为了将其作为默认道具传递给子级。家长不需要定义孩子的默认道具。孩子应该知道自己的默认道具是什么 因此,在我的初始父render()中,我将状态保留为未定义。当它

与类似,但我只对将子组件的默认道具放入父组件感兴趣

那我为什么要这么做呢

我有一个父组件,它呈现包含HTML表单的子组件。父级的render()方法将其状态数据作为道具传递给子级,这是它应该做的

最初,子表单应该只包含一些默认数据。从子组件中定义的defaultProps获取数据是有意义的。毕竟,我不想在父级状态下设置默认数据的负载,仅仅为了将其作为默认道具传递给子级。家长不需要定义孩子的默认道具。孩子应该知道自己的默认道具是什么

因此,在我的初始父render()中,我将状态保留为未定义。当它作为未定义的道具传递给子级时,子级将使用其defaultProps。这正是我想要的

时光流逝

现在,用户更改子组件窗体上的字段。我通过回调函数将更改传递回父级,以便它重新计算父级的新状态。然后,我调用父级中的
setState()
,将所有子组件重新渲染为正常

问题是我需要父对象的状态是一个对象,包含更多的嵌套对象,并使用[React Immutability Helpers][1]计算父对象中的新状态,如下所示:

handleFormFieldChange(e) {
// reactUpdate imported from 'react-addons-update'
 var newState = reactUpdate(this.state, {
    formData: {values: {formFieldValues: {[e.currentTarget.name]: {$set: e.currentTarget.value}}}}
    });
    this.setState(newState);
}
此代码第一次运行时,将抛出一个错误,因为它正在尝试更新状态值,并且没有要更新的状态。(我没有定义,记住!)

如果我试图通过将默认初始状态设置为空对象(每个对象都有嵌套的空对象)来绕过这个问题,我会遇到第22条军规。在第一次渲染时,这些空值将作为空道具传递给子组件,从而覆盖我为子组件设置的defaultProps。真倒霉

因此,就我所见,我需要一个合理的初始状态来传递给子组件,但不需要在父组件中再次(重新)定义整个组件。因此,在这种情况下,我认为将孩子的defaultProps拉入父对象是有意义的,只是为了设置父对象的初始状态


我有一种方法可以做到这一点,稍后我会发布。但在我这么做之前,有人有更好的方法吗?一个可以避免将默认道具从孩子传递给父母的方法?

正如在原始帖子中威胁的那样,下面是我如何将孩子的默认道具发送给父母的方法

我使用ES6类和模块模式,用Webpack和Babel来处理构建和传输

所以我有两个文件,让我们称它们为Parent.jsx和ChildForm.jsx。下面是ChildForm.jsx的外观(注意:代码不工作!):

类子窗体扩展了React.Component{
render(){
var fieldValues=this.props.formData.formFieldValues;
返回(
字段1:
);
}
}
导出函数getDefaultProps(){
返回{
表格数据:{
FormFieldValue:{
字段1:“苹果”,
字段2:“香蕉”
}
}
};
}
ChildForm.defaultProps=getDefaultProps();
导出默认子窗体;
诀窍是将defaultProps的设置移动到一个单独的函数,该函数也从ChildForm.jsx导出。完成之后,您可能会猜到我将在Parent.jsx模块中执行什么操作!让我们来看一看:

import reactUpdate from 'react-addons-update';
import ChildForm from "./ChildForm.jsx";
import {getDefaultProps as getChildFormDefaultProps} from "./ChildForm.jsx";

class Parent extends React.Component {
    constructor(props) {
        super(props);
        var formDefaultProps = getChildFormDefaultProps();
        this.state = {
            formData: formDefaultProps
        };
        this.handleFormFieldChange.bind(this);
    }

    handleFormFieldChange(e) {
        var newState = reactUpdate(this.state, {
            formData: {values: {formFieldValues: {[e.currentTarget.name]: {$set: e.currentTarget.value}}}}
        });
        this.setState(newState);
    }

    render() {
        return (
            <div>
                <ChildForm
                    formData={this.state.formData}
                    handleFieldChange={this.props.handleFormFieldChange} /}
            </div>
        );
    }
}
从“react addons update”导入reactUpdate;
从“/ChildForm.jsx”导入ChildForm;
从“/ChildForm.jsx”导入{getDefaultProps as getChildFormDefaultProps};
类父类扩展了React.Component{
建造师(道具){
超级(道具);
var formDefaultProps=getChildFormDefaultProps();
此.state={
formData:formDefaultProps
};
this.handleFormFieldChange.bind(this);
}
handleFormFieldChange(e){
var newState=reactUpdate(this.state{
formData:{values:{formFieldValues:{[e.currentTarget.name]:{$set:e.currentTarget.value}}
});
this.setState(newState);
}
render(){
返回(

如果您使用的是
React.Component
,那么
defaultProps
是类上的静态对象,因此很容易获取

export default class Child extends React.Component {

  static defaultProps = { ... }

}

// If you don't have es7 static support you can add it after the class def:
Child.defaultProps = { ... }
家长只需执行以下操作:

Child.defaultProps

访问它。

使用
React.Component
React.createClass
?我使用的是ES6模块,所以React.Component.confirmation对我有效。多明尼克,非常感谢。
Child.defaultProps