I absolutely love hooks and don't want to use the `React.Component` class ever again.
And yes, hooks need to be grasped, they're quite something else. But once you get the hang of hooks, they're very simple to understand.
OP seems to be a bit stuck in a hole.
If you end up in a situation where your hooks come loose and the code becomes a mess — just delete them all and rethink your code / component logic structure. Believe me, it all can be simplified. Just rinse and repeat until you are satisfied with the outcome. That's when the "aha!" moment comes.
At the moment I only use `useEffect`, `useState`, `useRef` — the rest is unneeded so far even in my large-ish application.
There are some weird edge cases with useEffect, no question.
I don’t think they’re bad enough to want to go back to using classes... but I think the OPs post was a bit more specific than you’re giving them credit for, and they stuff like useAsyncEffect exists because it is a common pain point.
The behaviour is weird sometimes; just because you can use the trivial use case easily doesn’t mean you won’t stumble, and if you do, good luck trying to understand what went wrong.
> ...they're very simple to understand...
They’re not simple.
They just superficially appear simple, which is good enough most of the time.
I think it’s entirely fair to complain that’s not ideal... even if you still think there’s a major benefit to the trade off compared to classes (which I do think is true too).
...but I’m very sympathetic to people hitting edge cases.
> If you end up in a situation where your hooks come loose and the code becomes a mess — just delete them all and rethink your code / component logic structure
“Just burn it to the ground and start over,” isn’t an inspiring endorsement of the methodology...
`useContext` is excellent. React.context is a solid alternative to the likes of Redux and Apollo, but takes a fair amount of boilerplate to add to a class based React component. But with `useContext`, applying global state is a breeze. A lot easier to manage than Redux, at the very least.
The only real dislike I have, is in how `useEffect` confuses the React lifecycle. It took me a little while to grok the lifecycle idea, but it was/is a useful way to conceptualise what happens to your components at runtime.
But now, you have to remap all that knowledge to the hooks workflow. It's not a huge challenge, but it's yet another overhead.
Indeed, starting out, our team ran into a number of issues with infinite rendering loops and the like. Took a fair amount of reading to discover where the pitfalls were.
We're slowly refactoring our class-heavy React app to functional components with hooks.
One thing we haven't been able to replace, though, are classes that depend on refs. How to do this, since there's no instance with functions like there are with classes?
I was extremely skeptical of hooks in the beginning after having used class-based lifecycle components for a long time. Overall, I _think_ it's been a net positive but I end up feeling that I'm writing more code at the expense of using well defined constructs (lifecycle methods).
I usually feel like I'm writing too many effects which update state(s) and the lifecycle flow becomes harder to contain mentally, however there are times where I'm like "this is definitely easier or less of a cluster then it use to be".
So I think the jury is still out. In terms of Hook's initial premise of "we're doing this so that developers unfamiliar with class-based OO paradigms can work better/faster", I don't think it added any more clarity or ease-of-use over the class based lifecycle methods tbh.
Maybe this is because I'm a "developer[] unfamiliar with class-based OO paradigms" but I find hooks components easier to read later. You start at the top, read to the bottom, and assuming you can catch crazy indirection within a hook callback during review, that's what happened. No HOCs. No having to memorize an externally documented lifecycle order. No having to cross-reference methods against the state they update 50-60 lines up the file.
I'm genuinely curious if the difference is because I was doing tons of Recompose/HOC style components before hooks came out.
Also, just FYI, it didn't click for me until this tweet[1]:
> The question is not "when does this effect run" the question is "with which state does this effect synchronize with"
Many people aren't event aware of the unnecessary renders caused by using hooks. If your app is so tiny that it doesn't matter if everything renders all the time, then you might not be aware of your `useCallback` recreating callbacks way too often (https://github.com/facebook/react/issues/14099), or that you're not even using it in the first place. Considering that front end is probably the area of software development that attracts the largest share of people like me - self taught, no computer science background - I'd also assume that many people love the perceived simplicity of hooks without realizing that it makes their code worse.
It'll only become apparent when you app is large and complex enough that it suddenly starts to matter when things re-render and then you'll be faced with tracking down those re-renders and fixing dependency arrays everywhere.
With classes, the naive solution is the right one when it comes to preserving function identities across renders.
Not saying hooks are bad, but they're not all roses and sushine.
A lot of people don't understand that React's default behavior is to re-render _everything_.
When a component is rendered, React will recursively re-render all descendants of that component. Out of the box, React doesn't do any optimizations like "skip rendering this component if the props haven't changed". Because of that, "re-creating callbacks" isn't an issue in base behavior [0], because there's nothing that cares if it's a new function reference or not.
It's only when child components are attempting to optimize perf by comparing props and avoiding re-renders that having consistent callback function references matters (ie, `React.memo()`, `PureComponent`, and React-Redux's `connect()`).
I have been working on an enterprise React App for the past 6 months using only the hooks API. The App is a non trivial Dashboard, displays various custom charts (done using d3 and manual SVG Elements in React) and some larger tables/forms. While I use useEffect() frequently, there is not a single useCallback/useMemo in the code.
I just profiled it on my 5 year old MacbookPro, and out of 50 commits or so, just a single one spiked above 20ms (which was the first commit, subsequent to same view were much faster) and almost all are in the <5ms range. I decided it is not worth doing any optimization yet, and I will defer useCallback/useMemo optimization until there is a real, noticeable delay in rendering.
> This is yet another JavaScript paradigm to learn. For the record, I am a 49-year-old React fanboy. I am a freelancer and use other frameworks apart from React, and this gives me fatigue.
Amen to that. The fact that still are in "here's a 'better' idea, let's try this" landscape in JavaScript is depressing.
I no longer jump on these new frameworks when the bandwagon flies by. I ignore postings for jobs saying they are rewriting their system in "new Framework Y!". I don't care how "pure" your new design is, I care about having it work well in the trenches.
React Hooks and Containerizing Everything are the things this old "Webmaster" is kicking down the road until all the bugs are shaken out. I also skipped gulp and grunt and jumped straight into webpack, which I've read far too much about to understand so little.
Overall I think React hooks are an improvement. My codebase is usually shorter and there is a lot less typing involved.
But hooks creates abstractions the developer needs to deal with that never existed before.
Hooks are not functional because they break referential transparency of functions.
You have to track dependencies manually and hooks are more difficult than they need to be for the "componentDidMount" equivalent. If you don't get the dependencies just right you end up with things not firing or in infinite loops.
You have to wrap your functions in "useCallback" or "useRef" just so the reference doesn't change and cause infinite loops.
You can't create abstractions where a hook calls another hook. So you end up having to inline a bunch more code into your function rather than outsourcing it into a helper function.
The positional order seems like it would be easy to work around if they allowed you to pass in a key. Not sure why that isn't available.
> The positional order seems like it would be easy to work around if they allowed you to pass in a key. Not sure why that isn't available.
IIRC it's because they implemented their own method lookup table (!) to associate with the Component object (!) but as a FIFO queue, more or less. I assume either for ideological (that's how they wanted it to work) reasons or because they (probably correctly) reasoned that loading down React apps with more strings at such a basic level would risk performance/memory problems. Plus if they did that then it'd really look like a method lookup table and be more obviously Rube-Goldbergian than it already is.
I never understood the need for hooks and how it's used (the example that react doc has for useState is too simplistic for any useful pedagogical reasons) until I saw divjoy's generated code and studied how it used hooks. Then everything clicked and I've been more productive using hooks than I ever had with react classes. I can attest that cognitive load is lower with hooks than with classes.
I don't agree with the author's statement that there are only two (very involved) solutions to the pagination problem
(re: section titled "React relies on the order in which Hooks are called").
It can easily be solved by just setting the state in the event handler, since the state is included in the dependencies array for the fetch effect:
> On line 23, the useFetch Hook will be called once on the first render. On lines 35 – 38, pagination buttons are rendered but how would we call the useFetch Hook from the event handlers of these buttons?
We can call `useFetch` again by triggering a re-render. This hasn't changed at all with the introduction of hooks: new props or new state still triggers a re-render.
I wondered about this too, in general I think the article misses that updating state is the key to "causing" effects. Rather than latching onto the callback model to explicitly "run" effects.
Though I'll admit getting the relationship of state and effects caused by changes to that state can be more difficult to work out mentally, I think it results in a more complete understanding of what a component actually does.
I spent maybe 1.5-2 years working on a medium size React app and after taking maybe 6 months off, I came back to it. I started reading about React Hooks and honestly I did not fully understand them. Maybe it's just JS fatigue and me feeling like I'm trying to building a house on quick sand. Everything is always changing...
Recently I built a bolierplate JSON-api web app project in vuejs and golang (previously I was using TypeScript, Apollo GraphQL and Express). I find the terminology around vuejs much more user friendly and it comes with a router and state management built in...I try to avoid using any other JS module. The golang ecosystem is much more stable than nodejs which is a relief....I have a feeling I might just settle on vuejs + golang for all future web apps
We’ve writing most new code with hooks (including the Apollo GraphQL hooks like useQuery and useMutation). Generally been really pleased with them but did get bitten hard the other day.
The value returned from useState is just a plain ol’ variable like any other so it also gets captured by closures like any another variable. We had an editor that updated some state and then an event handler (defined as a closure) that did something with the state variable. The state was updated as expected but when the event fired, the closure had the original value. It can be worked around via a container/useRef (and is maybe a code smell in the first place) but it made for some painful debugging.
Interesting to hear someone who clearly tried to use it seriously. That said I do agree with the first comment on the article itself, he is using his "useFetch" in a very far fetched (haha) way. A hooks should not be called as a callback to an event, you should "trigger an action" (whether redux, a callback from a higher component etc.) that update a state which in turns trigger the hook. I understand this can be length / annoyingly administrative but that is the cost of the react architecture, with the payoff being to better understand the flow of the application.
I use redux and react-saga for more complex flows, sagas translate into generators and make async code flows look almost like synchronous code which is nice.
useEffect is such a weird name. I get that it's kinda general in usecases but whenever I see the name my first thought is "what the hell is an effect and when do I use them?" and this is coming from someone who has actually heard about effect systems. Going from componentDidMount which is a nice, clear name that dictates when the function is run, to useEffect(() => console.log("Mounting!"), []) is so confusing. I'm not super thrilled that the difference between running on mount, on new props and on unmount is implicitly determined via the second argument or returning a new function. I get that useEffect has a nice coherence and is more general but that's not always a good thing.
Not to mention the docs for useEffect just mention the one usecase of running on mount and on update and neglect to even talk about running something just on mount.
That being said, the reducer hook is amazing and a great replacement for overly complicated setState or overly simple Redux stores. Definitely reminds me of ReasonReact in a good way.
What's lost in all this is that classes are simple and understandable. Introducing all these new paradigms removes that simplicity. Everyone is ready to hate on classes but they have been robust structures for a long time
I think it's fair criticism to say that hooks are extraneous to JavaScript. However, they are still a better tool for the job of building components, and they solve real and important issues around safety, maintainability and complexity. There are alternatives to JS, and alternatives to React in JS. I think it's good the React team chose this unique direction to make the best framework possible by taking advantage of JS's strengths to workaround it's weaknesses.
I think that what is lost is that Javascript is more of a functional language than an object-oriented one and a move to hooks embraces its functional roots while eliminating numerous footguns (this), simplifying reuse, and reducing redundancy.
I'm done with React. They keep re-inventing the wheel, and every iteration is full of issues that need to get resolved with yet another design principle.
I'm also frustrated with the introduction of a completely new paradigm, but to be fair to the React team, hooks are really innovative and don't re-invent the wheel at all. I, for one, have never used another framework that had anything similar to hooks.
Coming from a ClojureScript / Reagent background, functional components and hooks look very natural, useState being largely equivalent to reagent.core/atom. useEffect and useRef look like a logical extension of the same idea.
Hooks are absolutely fantastic. However, there are still a few pain points:
- useState with an array is bad news if more than 1 component is consuming or setting the state.The clunky alternative is to keep it in a ref & call a forceUpdate whenever you would normally call your setter
- useCallback doesn't scratch the itch for things like document event listeners since everything inside the callback will be stale. The clunky alternative is a custom useEventCallback that keeps your callback function in a ref. (and that might not work in the upcoming sync mode)
- linter rules can be too strict & the --fix flag can actually cause a break in your app by adding things to the dependency list. Sometimes a useEffect depends on the current value of a ref, but linter says that's a no-no. 2 useCallbacks can be co-dependent, but there's no way to write that co-dependence in the dependency list. Sometimes I want to return null before a hook. The clunky alternative for all these is a bunch of eslint-ignore comments.
> useState with an array with more than 1 component setting the state...
It sounds like you might be setting state by modifying the array and then calling the setter. This won't work:
array.push(thing)
setArray(array)
Instead, you have to update the array immutably, like setArray([...array, thing]).
> useCallback for event listeners
useEffect is usually the right place to set up event listeners (and has a built-in way of cleaning them up, by returning a cleanup function).
> Sometimes I want to return null before a hook.
Hooks pretty much have to be at the very top of the component, and eslint-ignore'ing those errors will probably cause weird issues later. Better to think about another way to solve the problem that doesn't involve returning early.
An issue I ran into recently: I had a modal Edit dialog with some form state that was initialized with the current values of the thing I wanted to edit. If that modal was always mounted and merely shown/hidden (<Modal isOpen={itemToEdit}/>), the state would be initialized once and wouldn't update when I changed the item-to-be-edited. The fix was to unmount the dialog, and only mount it when there was an item to edit, {itemToEdit && <Modal isOpen={true}/>}
One major point of the author is complaining that the dependency array in an effect is only compared by reference for objects and arrays.
To me this is a feature rather than a shortcomming: I use immutable data structures all the time (with array and object spread operators it is really easy to do so) and the effect will only update when it really needs to - thus only triggering a re-render (or rather reconciliation) when something has actually changed. This is in contrast to .setState() which triggered reconciliation regardless if a value actually changed.
The example in the article can be fixed very easily and doesn't require immutable data structures. If you're fetching something from a url and you don't want to fetch twice from the same url, make the dependency the url itself.
If you think of them as mostly just syntactic sugar for closure state variables wrapped up in the module pattern, it's not so bad. (This is how some of us have been writing D3.js code for years!)
Long time React user here, have started experimenting with hooks. My general sense is the useState hook is a pretty neat idea, but useEffect and friends need some work. Definitely doesn't have that same "completely makes sense, this is a great API" feel that I typically associate with React.
The most fascinating thing about React Hooks is the perceived false dichotomy of hooks vs old class API. The old class API was pretty bad and could have been improved without changing the paradigm. Take componentDidMount and cdUpdate: they could have been replaced by this.onMountOrUpdate(fn) : that would have both solved the ergonomic issues and allowed multiple event listeners to be set up by multiple custom 'component enhancers' (the equivalent of custom hooks).
The market is ripe for a React like framework that keeps JSX and first class components but goes away with hooks in favour of a couple of event listeners and stuff like this.getContext(ContextName). Maybe also add MobX to easily solve state management. Vue is pretty close except JSX / first class components are an afterthought.
[+] [-] bestest|6 years ago|reply
And yes, hooks need to be grasped, they're quite something else. But once you get the hang of hooks, they're very simple to understand.
OP seems to be a bit stuck in a hole.
If you end up in a situation where your hooks come loose and the code becomes a mess — just delete them all and rethink your code / component logic structure. Believe me, it all can be simplified. Just rinse and repeat until you are satisfied with the outcome. That's when the "aha!" moment comes.
At the moment I only use `useEffect`, `useState`, `useRef` — the rest is unneeded so far even in my large-ish application.
P.S. sorry for the puns!
[+] [-] wokwokwok|6 years ago|reply
There are some weird edge cases with useEffect, no question.
I don’t think they’re bad enough to want to go back to using classes... but I think the OPs post was a bit more specific than you’re giving them credit for, and they stuff like useAsyncEffect exists because it is a common pain point.
For example, this useRef / useEffect combo mystifies me even now: https://stackblitz.com/edit/react-ts-zhvuha
The behaviour is weird sometimes; just because you can use the trivial use case easily doesn’t mean you won’t stumble, and if you do, good luck trying to understand what went wrong.
> ...they're very simple to understand...
They’re not simple.
They just superficially appear simple, which is good enough most of the time.
I think it’s entirely fair to complain that’s not ideal... even if you still think there’s a major benefit to the trade off compared to classes (which I do think is true too).
...but I’m very sympathetic to people hitting edge cases.
[+] [-] marmada|6 years ago|reply
[+] [-] ohyes|6 years ago|reply
“Just burn it to the ground and start over,” isn’t an inspiring endorsement of the methodology...
[+] [-] dynamite-ready|6 years ago|reply
The only real dislike I have, is in how `useEffect` confuses the React lifecycle. It took me a little while to grok the lifecycle idea, but it was/is a useful way to conceptualise what happens to your components at runtime.
But now, you have to remap all that knowledge to the hooks workflow. It's not a huge challenge, but it's yet another overhead.
Indeed, starting out, our team ran into a number of issues with infinite rendering loops and the like. Took a fair amount of reading to discover where the pitfalls were.
[+] [-] jtreminio|6 years ago|reply
One thing we haven't been able to replace, though, are classes that depend on refs. How to do this, since there's no instance with functions like there are with classes?
[+] [-] wilsonrocks|6 years ago|reply
[+] [-] halfmatthalfcat|6 years ago|reply
I usually feel like I'm writing too many effects which update state(s) and the lifecycle flow becomes harder to contain mentally, however there are times where I'm like "this is definitely easier or less of a cluster then it use to be".
So I think the jury is still out. In terms of Hook's initial premise of "we're doing this so that developers unfamiliar with class-based OO paradigms can work better/faster", I don't think it added any more clarity or ease-of-use over the class based lifecycle methods tbh.
[+] [-] pkilgore|6 years ago|reply
I'm genuinely curious if the difference is because I was doing tons of Recompose/HOC style components before hooks came out.
Also, just FYI, it didn't click for me until this tweet[1]:
> The question is not "when does this effect run" the question is "with which state does this effect synchronize with"
> useEffect(fn) // all state
> useEffect(fn, []) // no state
> useEffect(fn, [these, states])
[1] https://mobile.twitter.com/ryanflorence/status/1125041041063...
[+] [-] YuukiRey|6 years ago|reply
It'll only become apparent when you app is large and complex enough that it suddenly starts to matter when things re-render and then you'll be faced with tracking down those re-renders and fixing dependency arrays everywhere.
With classes, the naive solution is the right one when it comes to preserving function identities across renders.
Not saying hooks are bad, but they're not all roses and sushine.
[+] [-] acemarke|6 years ago|reply
When a component is rendered, React will recursively re-render all descendants of that component. Out of the box, React doesn't do any optimizations like "skip rendering this component if the props haven't changed". Because of that, "re-creating callbacks" isn't an issue in base behavior [0], because there's nothing that cares if it's a new function reference or not.
It's only when child components are attempting to optimize perf by comparing props and avoiding re-renders that having consistent callback function references matters (ie, `React.memo()`, `PureComponent`, and React-Redux's `connect()`).
[0] https://reactjs.org/docs/hooks-faq.html#are-hooks-slow-becau...
[+] [-] littlecranky67|6 years ago|reply
I just profiled it on my 5 year old MacbookPro, and out of 50 commits or so, just a single one spiked above 20ms (which was the first commit, subsequent to same view were much faster) and almost all are in the <5ms range. I decided it is not worth doing any optimization yet, and I will defer useCallback/useMemo optimization until there is a real, noticeable delay in rendering.
[+] [-] eternalny1|6 years ago|reply
Amen to that. The fact that still are in "here's a 'better' idea, let's try this" landscape in JavaScript is depressing.
I no longer jump on these new frameworks when the bandwagon flies by. I ignore postings for jobs saying they are rewriting their system in "new Framework Y!". I don't care how "pure" your new design is, I care about having it work well in the trenches.
I, too, am tired.
And old.
[+] [-] enobrev|6 years ago|reply
[+] [-] bcheung|6 years ago|reply
But hooks creates abstractions the developer needs to deal with that never existed before.
Hooks are not functional because they break referential transparency of functions.
You have to track dependencies manually and hooks are more difficult than they need to be for the "componentDidMount" equivalent. If you don't get the dependencies just right you end up with things not firing or in infinite loops.
You have to wrap your functions in "useCallback" or "useRef" just so the reference doesn't change and cause infinite loops.
You can't create abstractions where a hook calls another hook. So you end up having to inline a bunch more code into your function rather than outsourcing it into a helper function.
The positional order seems like it would be easy to work around if they allowed you to pass in a key. Not sure why that isn't available.
[+] [-] bcyn|6 years ago|reply
Not sure if I understand you correctly, but isn't this the purpose of custom hooks? You should be able to freely call hooks within other hooks.
[+] [-] shantly|6 years ago|reply
IIRC it's because they implemented their own method lookup table (!) to associate with the Component object (!) but as a FIFO queue, more or less. I assume either for ideological (that's how they wanted it to work) reasons or because they (probably correctly) reasoned that loading down React apps with more strings at such a basic level would risk performance/memory problems. Plus if they did that then it'd really look like a method lookup table and be more obviously Rube-Goldbergian than it already is.
[+] [-] tjchear|6 years ago|reply
[+] [-] bcyn|6 years ago|reply
It can easily be solved by just setting the state in the event handler, since the state is included in the dependencies array for the fetch effect:
https://codesandbox.io/s/dependency-array-0u3sc
The answer to this question posed by the author?
> On line 23, the useFetch Hook will be called once on the first render. On lines 35 – 38, pagination buttons are rendered but how would we call the useFetch Hook from the event handlers of these buttons?
We can call `useFetch` again by triggering a re-render. This hasn't changed at all with the introduction of hooks: new props or new state still triggers a re-render.
[+] [-] tylerFowler|6 years ago|reply
Though I'll admit getting the relationship of state and effects caused by changes to that state can be more difficult to work out mentally, I think it results in a more complete understanding of what a component actually does.
[+] [-] Blackstone4|6 years ago|reply
Recently I built a bolierplate JSON-api web app project in vuejs and golang (previously I was using TypeScript, Apollo GraphQL and Express). I find the terminology around vuejs much more user friendly and it comes with a router and state management built in...I try to avoid using any other JS module. The golang ecosystem is much more stable than nodejs which is a relief....I have a feeling I might just settle on vuejs + golang for all future web apps
[+] [-] kevsim|6 years ago|reply
The value returned from useState is just a plain ol’ variable like any other so it also gets captured by closures like any another variable. We had an editor that updated some state and then an event handler (defined as a closure) that did something with the state variable. The state was updated as expected but when the event fired, the closure had the original value. It can be worked around via a container/useRef (and is maybe a code smell in the first place) but it made for some painful debugging.
[+] [-] iraldir|6 years ago|reply
[+] [-] concerned_user|6 years ago|reply
[+] [-] hardwaregeek|6 years ago|reply
Not to mention the docs for useEffect just mention the one usecase of running on mount and on update and neglect to even talk about running something just on mount.
That being said, the reducer hook is amazing and a great replacement for overly complicated setState or overly simple Redux stores. Definitely reminds me of ReasonReact in a good way.
[+] [-] nooyurrsdey|6 years ago|reply
[+] [-] kiliancs|6 years ago|reply
[+] [-] Unbeliever69|6 years ago|reply
[+] [-] flabbergast|6 years ago|reply
[+] [-] RussianCow|6 years ago|reply
[+] [-] unknown|6 years ago|reply
[deleted]
[+] [-] latte|6 years ago|reply
[+] [-] mattkrick|6 years ago|reply
- useState with an array is bad news if more than 1 component is consuming or setting the state.The clunky alternative is to keep it in a ref & call a forceUpdate whenever you would normally call your setter
- useCallback doesn't scratch the itch for things like document event listeners since everything inside the callback will be stale. The clunky alternative is a custom useEventCallback that keeps your callback function in a ref. (and that might not work in the upcoming sync mode)
- linter rules can be too strict & the --fix flag can actually cause a break in your app by adding things to the dependency list. Sometimes a useEffect depends on the current value of a ref, but linter says that's a no-no. 2 useCallbacks can be co-dependent, but there's no way to write that co-dependence in the dependency list. Sometimes I want to return null before a hook. The clunky alternative for all these is a bunch of eslint-ignore comments.
[+] [-] dceddia|6 years ago|reply
It sounds like you might be setting state by modifying the array and then calling the setter. This won't work:
Instead, you have to update the array immutably, like setArray([...array, thing]).> useCallback for event listeners
useEffect is usually the right place to set up event listeners (and has a built-in way of cleaning them up, by returning a cleanup function).
> Sometimes I want to return null before a hook.
Hooks pretty much have to be at the very top of the component, and eslint-ignore'ing those errors will probably cause weird issues later. Better to think about another way to solve the problem that doesn't involve returning early.
An issue I ran into recently: I had a modal Edit dialog with some form state that was initialized with the current values of the thing I wanted to edit. If that modal was always mounted and merely shown/hidden (<Modal isOpen={itemToEdit}/>), the state would be initialized once and wouldn't update when I changed the item-to-be-edited. The fix was to unmount the dialog, and only mount it when there was an item to edit, {itemToEdit && <Modal isOpen={true}/>}
[+] [-] k__|6 years ago|reply
You're component gets rerendered when the array changes and not when you got the right mix of lifecycle methods going.
But yes, it's not always obvious what changes you really care for.
[+] [-] matsemann|6 years ago|reply
[+] [-] littlecranky67|6 years ago|reply
To me this is a feature rather than a shortcomming: I use immutable data structures all the time (with array and object spread operators it is really easy to do so) and the effect will only update when it really needs to - thus only triggering a re-render (or rather reconciliation) when something has actually changed. This is in contrast to .setState() which triggered reconciliation regardless if a value actually changed.
[+] [-] latortuga|6 years ago|reply
[+] [-] bhousel|6 years ago|reply
They didn't click for me until I read this netlify blog post: https://www.netlify.com/blog/2019/03/11/deep-dive-how-do-rea...
If you think of them as mostly just syntactic sugar for closure state variables wrapped up in the module pattern, it's not so bad. (This is how some of us have been writing D3.js code for years!)
[+] [-] mmckelvy|6 years ago|reply
[+] [-] spion|6 years ago|reply
The market is ripe for a React like framework that keeps JSX and first class components but goes away with hooks in favour of a couple of event listeners and stuff like this.getContext(ContextName). Maybe also add MobX to easily solve state management. Vue is pretty close except JSX / first class components are an afterthought.