Giter VIP home page Giter VIP logo

Comments (16)

danielneal avatar danielneal commented on July 25, 2024 3

I really value the approach in this project of providing a minimal wrapper, and respecting the semantics of React. The atom interface did look like a nice idea at first, but I think you're correct in identifying that there's a mismatch. On balance, I think I'd personally prefer the clarity of using the [state setState] tuple as proposed in your merge request. Thanks for all the think-effort on this :)

from hx.

lilactown avatar lilactown commented on July 25, 2024 2

As far as I can tell, they’ve punted on trying to align Redux with Concurrent React’s scheduler. They’re essentially moving back to a similar architecture as v5, where they keep a synchronous store that dispatches renders to each component that subscribes to it.

AFAICT this is due to the fact that previous versions of Redux gave the guarantee that dispatch is synchronous, so that you can do something like:

dispatch(FOO_EVENT);

store.getState();

This is exactly the same expectation that is broken by representing React useState as a Clojure atom.

If we do not carry forward this expectation, I think we might be able to align ourselves with React’s scheduler and leverage its benefits when it finally lands in stable.

from hx.

lilactown avatar lilactown commented on July 25, 2024 1

Yeah. The global state management problem is one of the most interesting at the moment w.r.t. Concurrent React, which is probably one of the reasons they aren’t willing to do a stable release with it yet 😄 .

FWIW I have the very strange (in CLJS) opinion that maintaining state outside of the render tree is an anti pattern, but even trying to maintain “global” state inside the render tree is waiting on improvements to context.

I have one approach that I want to test before I call it completely infeasible to do without the React team improving context. It involves maintaining global state inside of a top-level useRef kept in context, and maintaining subscriptions inside of the components using local state. It could specifically take advantage of ClojureScript’s immutable data to be much more memory and CPU efficient.

I’ll see if I can come up with a POC in the next week or two - got to make sure I don’t spend too much of my limited brain power on this 😂

from hx.

lilactown avatar lilactown commented on July 25, 2024 1

Some discussions on the react-redux repo making for good reading:

reduxjs/react-redux#890

reduxjs/react-redux#1177

from hx.

orestis avatar orestis commented on July 25, 2024 1

Something that becomes really obvious the moment you start storing state in React -- hot reloading becomes a little bit more annoying, as React will re-run all your hooks and re-fetch all data from the backend.

So the defonce trick for state that survives hot reloads doesn't really work.

My hacky workaround is to have a top-level defonce and then use that until the fresh data comes back from the backend, so at least then I don't "loading state" flashes when I work on presentational stuff.

from hx.

lilactown avatar lilactown commented on July 25, 2024

cc @orestis @mhuebert @roman01la

Also I have created some devcards of the above examples in the master branch of this repo.

from hx.

lilactown avatar lilactown commented on July 25, 2024

Relevant article written by Andrew Clark: https://github.com/acdlite/rfcs/blob/context-write/text/0000-context-write.md#concurrent-invalidation

In it he talks about how maintaining state in a synchronous external store with concurrent renders can cause inconsistencies.

from hx.

DjebbZ avatar DjebbZ commented on July 25, 2024

Thanks for layout the issues so clearly. I would conclude the same thing as you, don't try to do non React thing, just embrace it.

But this raises a question for us Clojure(Script) developers: what could be the equivalent of global store in Clojure(Script) then? Should we just have a top level atom and add a watcher that re-render the top level component with the content of the atom passed as props (or React context) ? Use the useReducer hook and pass the dispatch function as props (or again pass it through context)? Just abandon Atoms and lose the observability they provide (this hurts somehow but may be ok)?

I'd love your thoughts on these questions, I don't have an answer.

from hx.

DjebbZ avatar DjebbZ commented on July 25, 2024

I've just read the proposal you linked from Andrew Clarke. Maybe we need to wait for a solution like this to allow using atoms and React together. What I mean is that we could reset! the atom in the contextDidUpdate callback, so that the UI and the state stay consistent. But not sure if it's doable or a good idea, would need to see what to come up with.

In the meantime, given React don't have stable APIs for scheduling state transitions... I don't know 😅

from hx.

DjebbZ avatar DjebbZ commented on July 25, 2024

I'm interested to see what you come up with. I also had the idea that keeping the global state inside the top-level component could be a solution. Looking forward to seeing it!

from hx.

lilactown avatar lilactown commented on July 25, 2024

I've created a PR that removes the Atom-like wrapper around useState, as well as optimizes certain cases where the state update fn might return a structurally equivalent but referentially different collection.

#42

This aligns us with the semantics of React and users can expect similar/API behavior as the React docs say.

Looking for feedback!

from hx.

DjebbZ avatar DjebbZ commented on July 25, 2024

React-redux seems to have found a solution, since they've released a beta of version 7, which uses hooks and seems to just store the "global" content inside the UI tree itself, to let React handle it. Admittedly I've glanced quickly only, so you may want to read it carefully https://www.reddit.com/r/reactjs/comments/b40y7u/reactredux_v700beta0_faster_performance_and_built/

from hx.

lilactown avatar lilactown commented on July 25, 2024

@orestis check out #44

from hx.

caleb avatar caleb commented on July 25, 2024

I don't use hx yet (I'm using Rum right now), but I'm keeping my eye on it because of the new stuff coming down the React pipeline (hooks, concurrent, etc), but I think this would be a good change to make it more consistent with React.

Are there synchronization issues with the component's state and an atom when using the <-deref hook? I'm trying to wrap my head around how I would do state management with hooks in hx. Right now each line of my form subscribes to updates on the global atom when that line changes. This is for performance reasons so I'm not creating a react virtual Dom tree for my whole app on every keystroke.

from hx.

lilactown avatar lilactown commented on July 25, 2024

Yes, <-deref is a foot-gun in concurrent React. Either you skip out on using scheduling with React, or you risk getting out or sync with your state.

from hx.

frankiesardo avatar frankiesardo commented on July 25, 2024

This is a very interesting discussion, thank you all for sharing it here. Shame I only become aware of it today!

I've been tinkering a lot about using something like citrus together with the React hooks. I like the colocation of state and side effect and the ability of supplying different effect handlers for e.g. testing that citrus gives you.

This is my best shot at recreating reducers with side effects in pure React, no extra atoms and observers.

https://gist.github.com/frankiesardo/d135c73d74695d83277c4294a987006f

I would love to hear the thoughts of people in this conversation since you've analysed the problem quite deeply

from hx.

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.