如何正确传递带有spread属性的嵌套属性?(JSX)

Kir*_*tov 12 javascript jsx reactjs

#1

你好.我有代码:

class Component extends React.Component
{
  render()
  {
    this.props.nested.prop = this.props.parse.nested.prop;
    return <div>Component</div>;
  }
  componentDidMount()
  {
    console.log(this.props.nested.prop);
  }
}
Component.defaultProps = 
{
  nested:
  {
    prop: "default"
  }
};

const obj1 = 
{
  nested:
  {
    prop: "obj1"
  }
};
const obj2 = 
{
  nested:
  {
    prop: "obj2"
  }
};

class Application extends React.Component
{
  render()
  {
    return (
     <div>
        <Component parse={obj1}/>
        <Component parse={obj2}/>
    </div>
    );
  }
}

React.render(<Application />, document.getElementById('app'));
//console output:
//"obj2"
//"obj2"
Run Code Online (Sandbox Code Playgroud)

为什么我为每个组件获得2个独立组件的1个变量引用而不是2个nested的nested.prop?为什么this.props在安装后只保存组件的所有实例的最后设置值?这是正常的行为吗?我认为正确的行为是针对不同的实例具有不同的属性值.

PS我在这里测试了这段代码.

#2

jimfb已被解答: "You are mutating the default prop that was passed in. The line this.props.nested.prop = this.props.parse.nested.prop; is illegal."

我的下一个问题: How to pass nested properties without a manual mutation of props?

例如:

Component.defaultProps = 
{
  nested:
  {
    prop1: "default",
    prop2: "default"
  }
};

const props = 
{
  nested:
  {
    prop1: "value"
  }
};

let component = <Component {...props}/>;
Run Code Online (Sandbox Code Playgroud)

上面的代码指南JSX传播属性功能只是覆盖props.nested,我失去了默认的嵌套属性.但这不是我需要的.如何在JSX传播属性解析阶段实现嵌套对象的递归遍历?
或者这种情况有一些有用的模式吗?

Ser*_*pin 20

这实际上是一个很好的问题!

简短的回答:你不能与扩散算子深度合并 - 它只能进行浅层合并.但是你肯定可以编写将遍历对象并实现深度合并的函数.

这实际上有三个选择:

1)只是不做深度合并.如果你有2级嵌套对象,你可以做这么简单的事情:

const newNested = {...oldProps.nested, ...newProps.nested };
const finalProps = { ...oldProps, nested: newNested };
Run Code Online (Sandbox Code Playgroud)

浅合并强制明确说明您将拥有嵌套属性的新值.这是一件好事,因为它会使您的代码变得明显.您也可以在这里试用可运行的示例.

2)您可以将库用于不可变结构.Fe immutable.js.有了它,你的代码看起来非常相似.

const oldProps = Immutable.fromJS({
  nested:
  {
    prop1: "OldValue1",
    prop2: "OldValue2",
  }
});

const newProps = Immutable.fromJS({
  nested:
  {
    prop1: "NewValue1",
  }
});

const finalProps = oldProps.updateIn(['nested'], (oldNested)=>
  oldNested.merge(newProps.get('nested'))
)
Run Code Online (Sandbox Code Playgroud)

3)你可以使用深度合并:在npm中找到一些实现或自己编写,你将得到这样的代码(再次以immutable.js为例):

const finalProps = oldProps.mergeDeep(newProps);
Run Code Online (Sandbox Code Playgroud)

在某些情况下你可能会想要这个,但是这样的代码会使更新操作隐含,并且会引发很多问题,这些问题在这里列出很多