如何正确传递带有扩散属性的嵌套属性?(JSX)
#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.prop实例?
为什么this.props在挂载后只为组件的所有实例保存最后设置的值?这是正常的行为吗?
我认为正确的行为是为不同的实例设置不同的属性值。
附注:我已测试此代码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传播属性特性上面的代码指南只需覆盖pros.nest,我就会丢失默认的嵌套属性。但这不是我需要的。
如何在JSX扩散属性解析阶段实现嵌套对象的递归遍历?或者这种情况下有什么有用的模式吗?
解决方案
这实际上是一个很好的问题!
简而言之:您不能使用扩散运算符执行深度合并-它只执行浅合并。 但您肯定可以编写遍历对象并实现深度合并的函数。这实际上给您留下了3个选择:
1)不要进行深度合并。如果你有两层嵌套的对象,你可以做这样简单的事情:
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
相关文章