GithubHelp home page GithubHelp logo

Comments (29)

mrGibi avatar mrGibi commented on June 10, 2024 1

Ok, both examples are working now. Thanks!

from reactive-react-redux.

theKashey avatar theKashey commented on June 10, 2024

Just give an example to fight with! (ok, there is a sandboxes)

from reactive-react-redux.

theKashey avatar theKashey commented on June 10, 2024

Working on Chrome, not working on Safari or FF

from reactive-react-redux.

theKashey avatar theKashey commented on June 10, 2024

In short - this is due to batchedUpdates. But it's not clear why it does not work as expected.

from reactive-react-redux.

mrGibi avatar mrGibi commented on June 10, 2024

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

dai-shi avatar dai-shi commented on June 10, 2024

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.

theKashey avatar theKashey commented on June 10, 2024

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.

theKashey avatar theKashey commented on June 10, 2024

@dai-shi - useProxyfied should use useLayoutEffect

from reactive-react-redux.

theKashey avatar theKashey commented on June 10, 2024

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.

dai-shi avatar dai-shi commented on June 10, 2024

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.

theKashey avatar theKashey commented on June 10, 2024

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.

mrGibi avatar mrGibi commented on June 10, 2024

Could you try this commit 10c9574 in store-state-for-updates branch?

Unfortunately this doesnt resolve the issue πŸ˜”

from reactive-react-redux.

dai-shi avatar dai-shi commented on June 10, 2024

Good to know. I will make a useLayoutEffect version. I’m not sure if I understand the second bullet, yet.

from reactive-react-redux.

theKashey avatar theKashey commented on June 10, 2024
  • state1 {a:1, b:1}, we are using only a.
  • 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.

dai-shi avatar dai-shi commented on June 10, 2024

Got it. It’s false positives. I wonder if that would cause other false negatives in some edge cases?

from reactive-react-redux.

theKashey avatar theKashey commented on June 10, 2024

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.

dai-shi avatar dai-shi commented on June 10, 2024

OK, let me make a fix.

from reactive-react-redux.

dai-shi avatar dai-shi commented on June 10, 2024

Here you go: db485e0
Would you try with this commit? @mrGibi

from reactive-react-redux.

mrGibi avatar mrGibi commented on June 10, 2024

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.

dai-shi avatar dai-shi commented on June 10, 2024

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.

mrGibi avatar mrGibi commented on June 10, 2024

I dont get it...

I had two examples showing the issue:

yield put({ type: "TURN_ON" });
yield delay(10);
yield put({ type: "TURN_OFF" });
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.

dai-shi avatar dai-shi commented on June 10, 2024

Please try the latest master.

from reactive-react-redux.

dai-shi avatar dai-shi commented on June 10, 2024

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.

theKashey avatar theKashey commented on June 10, 2024

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.

dai-shi avatar dai-shi commented on June 10, 2024

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.

dai-shi avatar dai-shi commented on June 10, 2024

@theKashey I also want your comment on this.

from reactive-react-redux.

theKashey avatar theKashey commented on June 10, 2024

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.

dai-shi avatar dai-shi commented on June 10, 2024

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.

dai-shi avatar dai-shi commented on June 10, 2024

https://www.npmjs.com/package/reactive-react-redux/v/2.0.0

from reactive-react-redux.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.