4 ms·
But afaiu, with state living outside of react, components have to be updated by hand? Or at least have state to be duplicated in them. I mean, if a control/tabl
by wruza 5y ago
But afaiu, with state living outside of react, components have to be updated by hand? Or at least have state to be duplicated in them. I mean, if a control/table gets a mutating event, you have to update both outside state and internal setState({input}) as well, otherwise input wouldn’t appear. And when outside state changes by itself, there should be a way to forceUpdate() with props or maybe a direct setState(). Am I right? At least MobX does exactly that behind its fancy object properties. I mean, I’m not saying react is restrictive, it’s just tedious and doesn’t even try to help if you claim ownership over your state.
you have to be careful to not re-render components unnecessarily in performance critical situations where you're rendering a lot of stuff
Interestingly mithril’s author, the library that I use in place of react, suggested that for humongous doms it’s better to split it into sub-apps. In short, you make a shallow component that mounts another entire “app” into its div on its mount, so that updates do not propagate downwards (the main app simply doesn’t know about subapps). Otoh, events propagate as expected due to regular dom. Personally I find mithril’s approach more outside-state compatible, if you don’t do funny tricks with event bubbling. If you’re not familiar with it, it’s the same hyperscript/vdom, but re-render()s everything after any event related to dom it controls, unless you tell it not to in a handler. That is fully out-of-your-way approach compatible with anything. Animations, jquery components, you name it. I don’t get why people choose react, which seems to be the opposite of that. What do you think I’m missing here?
And thanks for your time and the expanded reply!
Edit: frankly, I wouldn’t even bother with react and would just use what fits, but its presence is overwhelming in a sense of both community and job options. If there is a way to use it without abstraction pain, I’d like to understand it.
- thatswrong0 5y ago> components have to be updated by hand Most state libraries provide a mechanism by which you can "connect" components to parts of the state you care about, so that they automatically re-render when that part of the state changes. New props come in, and the components can decide what to do with them. > Or at least have state to be duplicated in them. I mean, if a control/table gets a mutating event, you have to update both outside state and internal setState({input}) as well, otherwise input wouldn’t appear. And when outside state changes by itself, there should be a way to forceUpdate() with props or maybe a direct setState(). Am I right? So this is where things get murky, regardless of what library you're using. In the application I work on, our stores generally reflect the source of truth in the backend, and it's real-time so the stores can update literally whenever. This puts two-way data binding you see in other libraries out of the picture. So most of our forms use local state, because we only want the data store to be updated with the final result the end user actually saves. Interaction wise, it wouldn't make sense to submit it anyways until the user blurs it or explicitly saves it (plus it would be unnecessarily expensive to constantly be saving to the backend every keystroke). And by keeping the state local, if an update comes in from the backend on the entity we're editing in the form, we can notify you that "Hey, someone else updated this!" while still keeping our form state, and letting us make the decision as to whether we want to overwrite it. But we could also choose to just override the form state if we so choose.. we could just look at the "connect"ed state we care about, and if it changes, overwrite the local state in the form. That's generally not desirable though from an interaction perspective. > In short, you make a shallow component that mounts another entire “app” into its div on its mount, so that updates do not propagate downwards We do the same thing in our application. Although the top level component technically re-renders when our data store changes (because it's stored in a top level context component), we just have memoized components beneath that take 0 props, which therefore don't re-render even when the parent re-renders. And we re-use this same pattern through the application, creating separated subtrees that only re-render when data they care about changes. So I think of our application like this: either user interaction occurs (like a form save), or the backend updates. This changes our data store (which tries to reflect the state on our backend). This update causes the components that care about that specific piece of information to re-render. Their children may choose to re-render or not. And then we wait for more interaction / backend changes. This is where the notion of "unidirectional data flow" comes from - it's basically just a tight one-way loop that drives the presentation of our application. Forms do muck this up a bit with their local state, but that's something I think _every_ application has to think about handling I will admit I only learned frontend development / React properly at my current company (previous used a messy Backbone.js app), so there might be simpler / better ways at this point, but I find it very easy to reason about our application as a result of this pretty explicit data flow + our architectural constraints.