#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"
为什么我为每个组件获得2个独立组件的1个变量引用而不是2个nested的nested.prop? 为什么this.props在安装后只保存组件的所有实例的最后设置值?这是正常的行为吗? 我认为正确的行为是针对不同的实体具有不同的属性值。
P.S。我已经测试了这段代码here。
#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}/>;
上面的代码指南JSX传播属性功能只是覆盖props.nested,我失去了默认的嵌套属性。但这不是我需要的。 如何在JSX传播属性解析阶段实现嵌套对象的递归遍历? 或者这种情况是否有一些有用的模式?
答案 0 :(得分:20)
这实际上是一个很好的问题!
简短的回答:你不能与扩展运算符进行深度合并 - 它只能进行浅层合并。 但是你肯定可以编写将遍历对象并实现深度合并的函数。
这实际上有三个选项:
1)不要做深度合并。如果你有2级嵌套对象,你可以做这么简单的事情:
const newNested = {...oldProps.nested, ...newProps.nested };
const finalProps = { ...oldProps, nested: newNested };
浅层合并强制您要明确明确您将拥有嵌套属性的新值。这是一件好事,因为它会使您的代码变得明显。 您还可以尝试可运行的示例here。
2)您可以将库用于不可变结构。 F.E. 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'))
)
3)您可以使用深度合并:在npm中找到一些实现或自己编写 并且您将拥有这样的代码(再次以immutable.js为例):
const finalProps = oldProps.mergeDeep(newProps);
在某些情况下你可能会想要这个,但是这样的代码会使更新操作隐式,并且会引发很多大量列出的问题here