Skip to content
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

Merged
merged 2 commits into from Aug 2, 2018
Merged

setState now creates new versions instead of mutating state #1170

merged 2 commits into from Aug 2, 2018

Conversation

mitranim
Copy link
Contributor

Addresses #1168.

@coveralls
Copy link

coveralls commented Jul 23, 2018

Coverage Status

Coverage remained the same at 100.0% when pulling 576c891 on Mitranim:master into b8a117a on developit:master.

Copy link

@dandv dandv left a 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', () => {
Copy link

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.

Copy link
Contributor Author

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.

@KevinDoughty
Copy link
Contributor

getDerivedStateFromProps in src/vdom/component.js renderComponent() also mutates state, you might want to create a test that implements it.

@KevinDoughty
Copy link
Contributor

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);
	});

@mitranim
Copy link
Contributor Author

@KevinDoughty Good catch! Added a similar change for getDerivedStateFromProps, with a test. Now it also creates new versions instead of mutating the state.

@dandv
Copy link

dandv commented Jul 30, 2018

Should also add tests for nested props, given this linkState bug.

@mitranim
Copy link
Contributor Author

@dandv Are you sure the bug still reproduces with this PR?

@dandv
Copy link

dandv commented Jul 31, 2018

@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.

@developit
Copy link
Member

developit commented Aug 1, 2018

I think we're good to merge this. Thanks for the tests and comment updates too, makes it feel a bit safer! :)

@marvinhagemeister marvinhagemeister merged commit 5410c7e into preactjs:master Aug 2, 2018
@marvinhagemeister
Copy link
Member

@mitranim Awesome, thanks for your PR 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants