问题
React suggests not to mutate props. I was operating under the impression that when props are passed in, they would be immutable or frozen.
The code below does not throw any errors and mutates the prop. Is this a bug?
try{
var a = this.props.a;
a.push('one')
a.push('two')
a.push('three')
console.log(a)
}catch(err){
console.log(err)
}
回答1:
I'm not sure of the exact reasoning behind it or if that's documented somewhere but I could take a guess:
Freezing any assignment to a variable is not easy or even necessarily possible outside of using new-ish or even as of yet unimplemented browser features. Also deep freezing all your props in your app could have performance implications and would certainly need to be removed for prod builds.
Can you freeze assignment of a primitive variable? I don't think so. I think babel does it with const by statically checking code at compile time.
And can you freeze objects without Object.freeze or ES7's proxy? Again I don't think so, the es5-shim readme says:
which you cannot possibly obtain in legacy engines
What if someone does mutate something? These props are shallow copied, meaning you won't affect the parent prop unless you modify a nested object. However even if you did it would't affect the app, as that would get wiped out on the next render (just like your modifications).
If I got something wrong please let me know! This is just my reasoning.
回答2:
It won't throw any error unless you frozen the object(props) explicitly.
Props are received from parents and immutable as far as the Component receiving them is concerned.
i.e React by default the props are immutable in the sense it is the concern of your component to maintain them as data received from parent and use as it is. Where as we can use state to maintain the local(component level data) that can be changed any time and keeping props contract with the parent.
回答3:
Seems like this is the same behavior as const has, you can't reassign the value, but you can still push to the array or add keys to an object because those are not protected. Anyway, despite the possibility to do those mutations, you should not do this.
this.props.a = [1,2,3]; won't work
this.props.a.push(123); will work.
this.props.a = {name: 'John Doe'} won't work
this.props.a.name = 'John Doe' will work
If you try to reassign a prop in your component a type error will occur.
Uncaught TypeError: Cannot assign to read only property a ...
回答4:
This is not true. Props are mutable by default. If you're using ES2015 you can make them read-only within your function be doing the following:
const { a } = this.props; // would create a const variable 'a'.
Same as:
const a = this.props.a;
While you won't be able to reassign 'a' now, you can still mutate it. Meaning, a = 'foo'; will throw an error, but you will still be able to do a.push('foo');.
If you want to use immutable data structures, try working with https://github.com/kolodny/immutability-helper or https://facebook.github.io/immutable-js/
来源:https://stackoverflow.com/questions/41641254/react-why-are-props-not-frozen