question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

stateChange event fires once for each property in the state due to incorrect object.assign use

See original GitHub issue

I implemented this code as written in https://css-tricks.com/build-a-state-management-system-with-vanilla-javascript/

I wanted to comment there, but the thread is closed.

Issue

I have say 12 properties in my state, and with each mutation, the whole state object gets replaced, thus the ‘stateChange’ event is getting fired 12 times.

Expected Behavior

Expected console.log output–

store.js:52 ACTION: changePage store.js:27 stateChange: currentPage: 1

Actual Behavior

Actual console.log output– ACTION: setLoadingState store.js:52 ACTION: changePage store.js:27 stateChange: currentPage: 1 store.js:27 stateChange: currentPage: 1 store.js:27 stateChange: lastPage: 0 store.js:27 stateChange: direction: down store.js:27 stateChange: isLoading: false store.js:27 stateChange: isGated: false store.js:27 stateChange: isChallenge: false store.js:27 stateChange: isLockedState: true store.js:27 stateChange: nickname: store.js:27 stateChange: showWave: false store.js:27 stateChange: challengePoints: 0 store.js:27 stateChange: challengePages: 3,5,7,10

Steps to Reproduce the Problem

  1. Add multiple properties to the state
  2. Subscribe to the ‘stateChange’ event
  3. Use the app in the browser and view console.log output

I can make a PR if we decide this change would be helpful.

Current Implementation self.state = Object.assign(self.state, newState);

Solution: Start with an empty object for mutating the state. self.state = Object.assign({}, self.state, newState); this.setTrap(); // then call a method to re-init the set trap Proxy

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:2
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
interactiveRobcommented, Feb 28, 2019

Right! I think @lospringliu was suggesting that we take out the object.asssign and just switch use a standard assignment instead.

Which off the top of my head is going to look like self.state = newState;

This fixes the issue with the set trap Proxy, and does not require the Proxy be re-added.

The problem with Object.assign I think, is that when you have matching keys in the source object and the new object, Object.assign will use a setter on every matching key to update the values from the new object. newState is the whole state object, thus Object.assign triggers the proxy X number of times.

Is there any case or reason where we should stand up for merging with using Object.assign here?

1reaction
lospringliucommented, Feb 28, 2019

the mutations return state, I think there is no need to merge states together using Object.assign, simply assign the returned state to the store state

Read more comments on GitHub >

github_iconTop Results From Across the Web

stateChange event fires once for each property in the state due to ...
I have say 12 properties in my state, and with each mutation, the whole state object gets replaced, thus the 'stateChange' event is...
Read more >
Updating an object with setState in React - Stack Overflow
I understand that React uses .assign() to. merge the old state object with the new object so shouldn't the second code work properly?...
Read more >
Amazon ECS events - Amazon Elastic Container Service
Container state change and task state change events contain two version fields: one in the main body of the event, and one in...
Read more >
Object.assign() vs Object Spread { … } In Angular Ngrx ...
We will continue by adding every needed property which has a new value and amounts to the actual state change. Another option would...
Read more >
Object.assign() - JavaScript - MDN Web Docs
assign () method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found