4 ms·
Could you explain how the opt out/opt in works? Im a bit confused
by lacrimacida 3y ago
Could you explain how the opt out/opt in works? Im a bit confused
- CharlieDigital 3y agoTake this example: const { useState } = React; function Person(props) { console.log('Render Person'); return (<span>{ props.identity.firstName } { props.identity.lastName }</span>); } function App (props) { console.log('Render Hello'); const [count, setCount] = useState(0); const einstein = { firstName: "Albert", lastName: "Einstein" }; return ( <div> <button onClick={() => setCount(count + 1)}>Increment</button> <Person identity={einstein} /> </div> ); } ReactDOM.render( <App />, document.getElementById('container') ); The `<Person />` component will redraw on each `increment`. Nothing changed. Why would it redraw? Because when the `App` component redraws, the `einstein` variable points to a new reference. React sees this as a change and redraws both `App` and `Person`. What looks like normal JavaScript here is not. To prevent this redraw, you have to opt out like this: const einstein = useMemo(() => ({ firstName: "Albert", lastName: "Einstein" }), []); Or know to move the reference outside of the `App` like this: const einstein = { firstName: "Albert", lastName: "Einstein" }; function App (props) { ... } Which is fine in this case because there are no dependencies on the component tree. This is the most common mistake I see in React that leads to bugs. It's not just objects, but also functions. This is also a redraw: const { useState } = React; function Logger(props) { console.log('Render Log') return (<button onClick={props.onClick}>Log</button>); } function App (props) { console.log('Render Hello'); const [count, setCount] = useState(0); const logConsole = () => console.log("HELLO, WORLD"); return ( <div> <button onClick={() => setCount(count + 1)}>Increment</button> <Logger onClick={logConsole} /> </div> ); } ReactDOM.render( <App />, document.getElementById('container') ); Why? Because on increment, the `logConsole` is a reference to a new function. So the `Logger` redraws as well. So here, you need to opt out once again by using `useCallback` or moving the function out of the component tree (fine in this case since there are no dependencies). The thing is that it looks like normal JavaScript but the React render cycle is the unseen; you have to be aware of moving things "out of the way" and "bringing them back" via a hook. React's render cycle re-evaluates entire component sub-trees for changes and if your component doesn't explicitly opt-out by preserving referential equality (`useState`, `useCallback`, `useMemo`, etc.), you'll trigger a redraw downstream. These hooks effectively move the references out of the component tree and pull them back in when the tree re-renders and thus preserve referential equality. So what teams might do is after experiencing this one time chasing down a bug is wrap every single declaration in a hook to reduce the mental burden. This then creates other issues like performance and memory. Vue, for example, is the opposite because it has fine-grained reactivity. Nothing redraws until you opt in by using the Vue reactivity primitives.
- lacrimacida 3y agoGot it. Thanks for the thorough explanation
- CharlieDigital 3y agoYou bet. But if you grok that simple example, you can see why teams that switch to Svelte, Solid, Preact, or Vue feel "refreshed". This mental burden of trying to figure out what has to be put where just...goes away. The React model tries to bend JavaScript to conform to it's render cycle rather than designing to JavaScript's unique object-functional strengths.
- lacrimacida 3y agoThanks. A while ago I sensed the churn dangerzone around React and I refused to get on any React projects. I feel lucky that I had that option. I did some Angular projects (i think it was version 8-9) and to me it seemed okay at the time. The project evolved nicely and structurally it organized itself quite well. But there is a ton of boiler plate there as well and I’d avoid Angular in the future. Im doing mostly back-end work these days to keep my sanity.
- deleted 3y ago[deleted]
- ttfkam 3y agoAfter all this time, React's sheer tonnage of boilerplate still astonishes me. That abstraction leaks like useMemo(…) even need to exist in the first place… Folks want to solve their own problems, but they keep getting saddled with React's as well.
- CharlieDigital 3y agoEvan You (creator of Vue) had a great quote on this: > The pain and suffering of hooks all roots from the mismatch between a dogmatic belief in the superiority of immutability and the harsh reality of the host language that is JavaScript (Feb 25, 2023) This fundamental misalignment with React and JavaScript is the billion dollar mistake.