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
Pending state updates may be confusing #122
Comments
It might be best to think of |
Agree that isolating mutations to one place is good, but it sounds like you're suggesting making state-setting more awkward just to discourage it, which doesn't make sense to me. Will continue to think about this as I finish up the setState batching. My gut feeling right now is that updating |
Unfortunately this looks hard to change due to the arguments that the component lifecycle methods take. |
Any more concerns about this? I'm guessing this is still an issue, though I'm not sure how often people are hitting it. I think another option would be to simply restrict you to a single |
Until we hear more, I think it's fine to close this out. I haven't heard of anyone actually getting confused. |
One issue with updating this.state, even though you haven't flushed it accordingly, is that your system (React) is not consistent with itself. So for example, if you have a |
...and leave the last rendered state in currentState, as suggested in https://groups.google.com/d/msg/reactjs/R61kPjs-yXE/bk5AGv78RYAJ. This is a breaking change in that now componentWillUpdate and shouldComponentUpdate need to look at this.currentState when comparing, _not_ this.state. (Perhaps that's an argument towards including prevProps and prevState as arguments to those lifecycle methods...) Fixes facebook#122.
If you include closures in your render function as callbacks you can have similar problems. Likewise refs can be inconsistent, but also props if your parent doesn't flush down to you before your callback is invoked. Deferred reconciliation (batching) puts the whole system in an inconsistent state and to do this correctly you really have to reconcile anything that you may have dependencies on during your side-effectful operation. It turns out that this is a much more complex issue that this.state alone. |
I think I have made progress on the double setState problem using a cursor-based approach. http://jsfiddle.net/dustingetz/SFGU5/ (Past discussion is also here: #629) |
If anyone is paying attention, here is an improved cursor example that I consider idiomatic, no double setState problem, and uses |
I just ran into this problem as well.
When calling Please fix this! EDIT: So I can get around it in this case by placing the call to |
I'm also currently having the issue where I'm not really sure what |
Edit: also check out Douglas' answer on this StackOverflow question as that may be enough to solve your problems without this workaround. @nambrot if you're looking for a quick fix, what I ended up doing is creating a Utility function which wraps
then just change your You will also lose the generated Disclaimer: this isn't super well tested, so let me know if you have any problems with it. |
I ran into the same problem as @azoerb |
+1, the same problem, as @azoerb |
@th0r |
Could there just be a queuing function like |
The other workaround is to move your state out of React and into flux stores. As long as you keep state of out React then you shouldn't have this problem. |
@briandipalma Can you explore this? I thought a common convention was to setState when flux stores change otherwise there will be a hard time getting the change to render from the event handler? |
@ptomasroos Yes and the setState call is passed the state provided by the store, the React component doesn't calculate itself based on this.state. |
@briandipalma Good then we agree! Just wanted to be explicit. 👍 |
DISCLAIMER: I'm new to React. If I understand correctly, React's For In fact, we often CAN'T use Takeaways
Again - I'm new to React. Please clarify if I've got something wrong. |
@aldendaniels I think you've mixed two concepts. You're 100% correct about However independent of any In fact, you should never mutate |
Hi @leebyron - thanks for reaching out.
I'm a little dubious: from the React docs - "React lets you use whatever style of data management you want, including mutation". I also see that in Facebook's official TodoMVC Flux Example, state is not being treated as immutable. Using immutable state in JavaScript without using a 3rd party library like those listed in my previous post quickly becomes slow and tedious when dealing with large, nested data sets. If mutable state really is anti-pattern, then I'm all ears - but I'm also concerned by the invasiveness of the requirement. |
Wrote some thoughts about why React works this way: #11527 (comment) |
Prevent default on all key navigations
Oh React. If you call `setState` twice during the same execution frame, the second time, `this.state` will be the same as the first time. Thus, the second time will clobber the changes made the first time. This is a known issue: facebook/react#122 Btw, I noticed this when running the examples and trying the one with all the boxes; mouseLeave on one box gets called in the same frame as mouseEnter on another, and since all the boxes are in one component, they clobbered each others state, and everyone stayed hovered. Too lazy to write a proper test for this right now.
If you have
then
x
will only be incremented once because the new state will just be stored in_pendingState
untilreceiveProps
finishes. After my refactoring in #115, this will never increment twice, which is probably confusing.Maybe this isn't a bug. We can fix this behavior by instead updating this.state immediately (but still updating the UI later). Right now I can't think of any situations where having this.state out of sync with the UI is a problem.
@vjeux suggested I open an issue, so here I am. Probably easiest for me to fix while updating #115 though.
The text was updated successfully, but these errors were encountered: