React建议不要改变道具。我的印象是,当传递道具时,它们将是不可变的或冻结的。
下面的代码不会抛出任何错误并改变道具。这是一个错误吗?
try{
var a = this.props.a;
a.push('one')
a.push('two')
a.push('three')
console.log(a)
}catch(err){
console.log(err)
}
答案 0 :(得分:1)
我不确定背后的确切推理,或者是否在某处记录了但我可以猜测:
冻结对变量的任何赋值并不容易,甚至不可能在使用new-ish之外,甚至是未实现的浏览器功能之外。同样深度冻结你的应用程序中的所有道具可能会产生性能影响,并且肯定需要删除prod构建。
你能冻结原始变量的分配吗? 我不这么认为。我认为babel通过在编译时静态检查代码来使用const
来完成它。
你可以在没有Object.freeze或ES7代理的情况下冻结对象吗? 我再也不这么认为,es5-shim自述文件说:
你无法在传统引擎中获得
如果有人改变某些内容怎么办? 这些道具是浅层复制的,这意味着除非修改嵌套对象,否则不会影响父道具。但是,即使你这样做也不会影响应用程序,因为在下一个渲染中会被删除(就像你的修改一样)。
如果我出错了,请告诉我!这只是我的推理。
答案 1 :(得分:0)
似乎这与const
具有相同的行为,无法重新分配值,但您仍然可以推送到数组或向对象添加键,因为那些没有受到保护。无论如何,尽管有可能做这些突变,你不应该这样做。
this.props.a = [1,2,3];
无法工作
this.props.a.push(123);
将有效。
this.props.a = {name: 'John Doe'}
无法工作
this.props.a.name = 'John Doe'
将有效
如果您尝试重新分配组件中的道具,则会出现类型错误。
未捕获的TypeError:无法分配给只读属性a ...
答案 2 :(得分:0)
除非您明确冻结对象(props),否则不会抛出任何错误。
收到来自父母的道具,并且就接收它们的组件而言是不可变的。
,即默认情况下,props
是不可变的,因为组件需要将它们作为从父级接收的数据进行维护并按原样使用。我们可以使用state
来维护可以随时更改的本地(组件级别数据)并保持道具与父级合同。
答案 3 :(得分:-1)
事实并非如此。道具默认是可变的。如果您正在使用ES2015,您可以在您的功能中将它们设为只读:
const { a } = this.props; // would create a const variable 'a'.
同样:
const a = this.props.a;
虽然你现在无法重新分配'a',但你仍然可以改变它。意思是,a = 'foo';
会抛出错误,但您仍然可以执行a.push('foo');
。
如果您想使用不可变数据结构,请尝试使用https://github.com/kolodny/immutability-helper或https://facebook.github.io/immutable-js/