Comments (29)
Ok, both examples are working now. Thanks!
from reactive-react-redux.
Just give an example to fight with! (ok, there is a sandboxes)
from reactive-react-redux.
Working on Chrome, not working on Safari or FF
from reactive-react-redux.
In short - this is due to batchedUpdates
. But it's not clear why it does not work as expected.
from reactive-react-redux.
@theKashey latest Chrome? On mine its not working on at most second/third click.
Another example, much simpler, based on @dai-shi codesandboxes from README.md: my codesandbox fork. There's a "multiple" button which triggers two dispatch()
, one after the other. Component is not updating until you click "+1" or "-1" buttons.
from reactive-react-redux.
Thanks for the example. You are already helping very much with it. @mrGibi
I think this might be related with my thoughts on #15.
Could you try this commit 10c9574 in store-state-for-updates
branch?
(I'm trying it too, but codesandbox doesn't accept installing a npm package with commit???)
from reactive-react-redux.
So - by the time second update hits comparison
- the last state is not yet stored in lastProxyfied.current.state
- store update
- force update
- component rerender with a new store
- use effect to save a new store
- store update
- comparison with an old store
- no update
lastProxyfied.current.state
update
from reactive-react-redux.
@dai-shi - useProxyfied should use useLayoutEffect
from reactive-react-redux.
In short - a new store update got triggered while an old update is not fully "commited".
- or use
layoutEffect
- it's almost sync after the render - or update
lastProxyfied.current.state
after successful comparison (you have "used" it)
from reactive-react-redux.
useProxyfied should use useLayoutEffect
Oh... I thought about that before, but yeah.
Does this #20 (comment) also help?? (maybe not. it's a different problem.)
(I've got to leave now... π )
from reactive-react-redux.
Yeah, concurrent mode. Actually, we have got tearing here, when different pieces are using states from different times.
So
- use
layoutEffect
to close rendering, or else you may record proxy results from more than one render. - update
lastProxyfied.current.state
in the comparison function just after comparison, cos you dont need to defer it to record used keys, and you have to update it, as long as comparison with a "real" state was just made, and you dont want to redo it again, which would be the case, if state got changed one more time before a real render take a place.
from reactive-react-redux.
Could you try this commit 10c9574 in
store-state-for-updates
branch?
Unfortunately this doesnt resolve the issue π
from reactive-react-redux.
Good to know. I will make a useLayoutEffect version. Iβm not sure if I understand the second bullet, yet.
from reactive-react-redux.
- state1
{a:1, b:1}
, we are using onlya
. - component render
- inner state update
- state2 update
{a:2, b:2}
- change detected, force update - state3 update
{a:2, b:3}
- change detected, force update
Internal state was not yet updated, as a result the second comparison with an old state and a quick state update is a false positive, and might took more time than a comparison with state2.
So - once you compare a
and b
- set a=b
from reactive-react-redux.
Got it. Itβs false positives. I wonder if that would cause other false negatives in some edge cases?
from reactive-react-redux.
Should not. You already triggered redraw
, and it would commit the "used" state in a proper time.
So - even if by any reason (Concurrent) render did happen with older state - useLayoutEffect
would update the record as it should - "state used by fact".
from reactive-react-redux.
OK, let me make a fix.
from reactive-react-redux.
Here you go: db485e0
Would you try with this commit? @mrGibi
from reactive-react-redux.
db485e0
didnt help π
Since you pushed to master, we can use it on Codesandbox by using:
"dependencies": {
// ...
"reactive-react-redux": "github:dai-shi/reactive-react-redux",
// ...
},
in package.json
. Click here to open this codesandbox.
Its based on your example from README.md
but with additional multiple
button that triggers two dispatch()
in Counter.tsx
. As you can see, clicking multiple
button doesnt trigger component update.
Additionaly you can use my example repo on localhost with this:
git clone https://github.com/mrGibi/reactive-react-redux-tests.git
cd reactive-react-redux-tests/
npm install
npm start
from reactive-react-redux.
Oh... It wasn't about useLayoutEffect nor updating state.
It's about useForceUpdate. @theKashey
I didn't expect useReducer bails out for boolean.
Interestingly, if you add one more dispatch, it works. @mrGibi
const hc = () => {
dispatch({ type: "increment" });
dispatch({ type: "increment" });
dispatch({ type: "increment" });
};
If you have another to make them four, it won't.
from reactive-react-redux.
I dont get it...
I had two examples showing the issue:
- One example from my initial post: using
reactive-react-redux
1.8.0 together with redux-saga that triggered:
yield put({ type: "TURN_ON" });
yield delay(10);
yield put({ type: "TURN_OFF" });
- and second example with
multiple
button: codesandbox here that triggered:
const hc = () => {
dispatch({ type: "increment" });
dispatch({ type: "increment" });
};
I thought that both examples are pretty much identical, but the second one was just simplified version of the first one. Its all about making two (or more) fast changes to the state and component not being aware of those changes, right?
Well it turns out that they are not as similar as I thought, becouse after your latest commit to master, the first example (now using latest reactive-react-redux
from github/master) is working correctly. See here.
And the second example with:
const hc = () => {
dispatch({ type: "increment" });
dispatch({ type: "increment" });
};
now using latest reactive-react-redux
from github/master (codesandbox) still doesnt work π€·ββοΈ
from reactive-react-redux.
Please try the latest master.
from reactive-react-redux.
So, the question remained to me is whether we really need useLayoutEffect
. @theKashey
- state1 {a:1, b:1}, we are using only a.
- component render
- committed & inner state update
- state2 update {a:2, b:2} - change detected, force update
- component render, which uses b
- state3 update {a:2, b:3} - no change detected
- committed & inner state update
- no update (false negatives)
So, your approach totally depends on useLayoutEffect
run 100% sync.
from reactive-react-redux.
Yes. As long as you might have multiple renders before single useEffect
, and you have to track purely only one render - you have to useLayoutEffect
. You have to "close" tracking just after render.
from reactive-react-redux.
If we both revert useLayoutEffect
and "close" tracking", it still works (no false negatives).
We have false positives (#20 (comment)), though it's different from what is happening to @mrGibi 's example.
If both are correct, oh and if we solve the concurrent mode issue in the future, we don't need useLayoutEffect
.
I just feel like useLayoutEffect
is a last resort we'd like to avoid unless we have a real problem.
from reactive-react-redux.
@theKashey I also want your comment on this.
from reactive-react-redux.
If we both revert useLayoutEffect and "close" tracking", it still works (no false negatives).
π€·ββοΈ I am not sure why it works. Give me some time to play with it.
from reactive-react-redux.
If both are correct, oh and if we solve the concurrent mode issue in the future, we don't need useLayoutEffect.
This "if we solve the concurrent mode issue" is kind of strong condition more than I thought on the previous day.
I saw useIsomorphicLayoutEffect
in react-redux thread, which works around the warning issue, so I'd follow that.
from reactive-react-redux.
https://www.npmjs.com/package/reactive-react-redux/v/2.0.0
from reactive-react-redux.
Related Issues (20)
- Try new proxyequal HOT 19
- Stale props issue in selector API HOT 10
- Question: Ease of gradual transition to hooks concern HOT 3
- Add comparison with react-redux v7.1 in README
- Benchmarking with cocktails app by mikeyhogarth HOT 5
- Why calculateChangedBits = () => 0 HOT 16
- Discussions about proxy-polyfill HOT 1
- Benchmarking state usage tracking and other related projects HOT 5
- "Please use <Provider store={...}>..." exception unable to track down root cause HOT 3
- 'Please use <TrackedState...>' exception. Need help! HOT 6
- useTrackedState on an array does not trigger a rerender of FlatList with the extraData prop HOT 4
- Question about re-evaluation strategy HOT 9
- False negatives in tracking with React.memo
- A new API for reverting proxy
- Discussion: Antipattern to recommend `useTrackedSelector` HOT 4
- Testing Environment Slowdown HOT 4
- getUntrackedObject always returning null HOT 3
- SSR and `useLayoutEffect` issues warning in dev mode HOT 2
- Why is "patchStore" not exporte? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from reactive-react-redux.