New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
setState
now creates new versions instead of mutating state
#1170
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does fix my #1169 test case. @developit, please merge as soon as you get a chance, and publish a new package version, since this fixes a really insidious class of bugs.
@@ -1325,6 +1325,38 @@ describe('Lifecycle methods', () => { | |||
}); | |||
|
|||
|
|||
describe('#setState', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could I suggest also including a test of the function parameter version of the function. It looks like you are passing prev
by reference here, so wouldn't any changes to it also mutate prev? It would be interesting to explore the effects of that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion, I just feel like a full setState
test suite is somewhat out of scope for the PR. Strange that it's missing though.
Yes it passes the previous state by reference, exactly as it should. Treating the previous state as immutable is the responsibility of the user.
getDerivedStateFromProps in src/vdom/component.js renderComponent() also mutates state, you might want to create a test that implements it. |
This test still fails: it('getDerivedStateFromProps should not mutate state', () => {
const stateConstant = {};
class Stateful extends Component {
constructor() {
super(...arguments);
this.state = stateConstant;
}
static getDerivedStateFromProps(props,state) {
return { key: 'value' };
}
componentDidMount() {
expect(stateConstant).to.deep.equal({});
}
}
render(<Stateful />, scratch);
}); |
@KevinDoughty Good catch! Added a similar change for |
Should also add tests for nested props, given this linkState bug. |
@dandv Are you sure the bug still reproduces with this PR? |
@mitranim: the linkState bug? I haven't tried to repro it with this PR because linkState works with React as well, and I've just confirmed that the bug reproduces with React too. I was just suggesting adding tests for nested props since it's a tricky enough situation that linkState was tripped by it. |
I think we're good to merge this. Thanks for the tests and comment updates too, makes it feel a bit safer! :) |
@mitranim Awesome, thanks for your PR 🎉 |
Addresses #1168.