Goodbye, useEffect: David Khourshid
ฝัง
- เผยแพร่เมื่อ 5 ก.ย. 2024
- Recorded live at Reactathon 2022. Learn more at reactathon.com
Goodbye, useEffect
From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. Thankfully, there is a science (well, math) to side effects, formalized in state machines and statecharts, that can help us visually model and understand how to declaratively orchestrate effects, no matter how complex they get. In this talk, we’ll ditch the useEffect hook and discover how these computer science principles can be used to simplify effects in our React apps.
Aboud David Khourshid
David is a software engineer who loves playing piano and is passionate about animations, state machines, cutting-edge user interfaces, and open-source. Previously at Microsoft, he is now the founder of Stately, a startup focused on making even the most complex application logic visual and accessible to developers and non-developers alike.
Event production and post-production by EventLoop. Let's build your conference brand, or take it to the next level. info@eventloop.app - วิทยาศาสตร์และเทคโนโลยี
Great explanation. A bit unrelated but that font is a bit confusing at first glance, parentheses looks like square brackets.
Thanks for the feedback! I will change the font for future presentations.
@@davidkhourshid4450 thanks to you for sharing your knowleadge.
I scrolled down just to see this comment.
@@davidkhourshid4450 just as a curiosity, do you use that font regularly? I find it interesting how different people see stuff, it would drive me insane lol. Thanks for the presentation,really interesting, I hadn’t thought of xstate as a way to get rid of useState which is awesome.
i hate that font!
The real valuable takeaway here IMO is this reducer design pattern (15:02):
Changing your reducer from this:
(state, action) -> nextState
To this:
(state, action) -> [nextState, effectsData]
Typical reducer usage is getting that nextState and then calling setState(nextState) to run the React render.
Now, in addition to next state the reducer also provides data that describes any effects that should happen (e.g. an API request)
So before you call setState(nextState), you should process any effects based on that data (e.g. performing a fetch)
Your top level app function could look something like this:
let state = ...initial state...
function runMyApp(action) {
let [nextState, effectsData] = myAppReducer(state, action)
...process any effects (e.g. performing fetch)...
state = nextState
yourReactUI.setState(state)
}
Then in your react components, all your event handlers do is dispatch actions to this top level function.
Any event callbacks, e.g. a fetch request callback, can also dispatch actions to this top level function.
A simple example for some data that describes an effect: {type: "apiRequest", id: 123, method: "get", url: "users"}
Upon your reducer returning this data, you can do something like the following:
fetch(url).then(response => response.json()).then(data => runMyApp({ ... build action from data ... }))
React components aren't the only things that can dispatch actions to your top level function. You can dispatch in pretty much any callback listening to any event.
Personally I like to make a distinction between pure (underivable) state, derived state, and ui props (for React components)
Like so:
let state = ...initial state...
let derivedState = null //optional, for performance reasons only
function runMyApp(action) {
let [
nextState,
nextDerivedState,
effectsData
] = updateMyApp(state, derivedState, action) runMyApp(createAction(data)))
}
...process other effects...
state = nextState
derivedState = nextDerivedState
yourReactUI.setState(derivedState.uiProps) //UI props are just part of the derived state
}
This is basically how I design all my software applications -- web, mobile, and desktop apps -- regardless of language or technology.
I would love to see a more real world example of this. Even a smaller "dashboard" app with 2-3 different pages would be enough. I've gotten so used to data fetching in useEffect that it's hard to get rid of it mentally. I also don't use state management libraries or data fetching libraries 99% of the time because for most cases I work on, I've seen that I don't really require them.
To be honest, if I didn't do data fetching in useEffect, I would barely use that hook considering that API calls are main things I usually put in useEffect.
react query?
@@codefinity "I also don't use state management libraries or data fetching libraries 99% of the time because for most cases I work on, I've seen that I don't really require them."
I really never got into using it. I've heard nice things about it, just didn't test it properly.
@@rand0mtv660 Well, beyond just getting rid of `useEffect`, there are many advantages to react query. Like any thing, doesn't make it perfect for everyone though.
@@rand0mtv660 React query is a great library for data fetching. I mean with that you don't even need state management. It handles fetching, loading and caching and so you can use data anywhere in your application. Also it has great mutation features. Let's say you will add a new comment on your application. You can use useMutation and with that you just say insert this comment to UI even network request is not completed yet, but if anything goes wrong just roll it back. So it makes great user experience with it. Also you don't have to re-write all boilerplate again and again. I think you should try it once.
@@hamitaksln Yeah I've heard great things about it. It's definitely on my todo list of things I need to test and evaluate, but I just never got to it.
Man just made me go in and replace our in house React templates to use Suspense instead of useEffect wrappers for async calls. Enjoyed the whole process!
I'll use vue for the next project, thanks!
Definitely learned some things about useEffect in React 18 that I wasn't aware of. Really appreciate this, except that I'll have to go into work and tomorrow clean up some places that I'm sure I've misused that hook. Damn.
when we will stop solving issues with react or react hooks. so we could start thinking of developing our own app ...
REACT ===> STUPIDITY HELL
@@kumailn7662 *proceeds to program own hardware
Ever since I started using Svelte I realized that the next step in frontend technologies are JS compilers and that all other frameworks are just nice attempts but not the right solution. This video just shows how much
Yep, 26 minutes of trying to make React happy. Why? React should work hard to make me happy and efficient, not vice versa.
@@alexnezhynsky9707 yeah I keep seeing the comments and keeping thinking to myself how this is hell and a framework that tries to pride itself on saying it’s easy to learn should never have gotten to this point of redundant use effects confusing lifecycle and dozens of community tools trying to monkey patch all of the crap while still delivering middling performance
@@feritperliare2890 THANK YOU! I remember the hate of angular 2+ tears ago because it is complicated (and I agree it is complicated) but at least once you learnt the tool it made sense. React with the hooks is really just messing with us. Will try svelte to check.
People forget that you can use several useEffects, each one with a different dependency array.
exactly. just get your component to update a hundred times a second, what's the problem?
@@ChrisHaupt The same as if you use componentDidUpdate for stateful components, but with the advantage that you can write one function for each param you want to watch.
@@ChrisHaupt 🤣🤣🤣
@@ChrisHaupt That's not how that works...
@@ChrisHaupt batch
I love how this is an absolute cluster fuck. Only use useEffect for this, well and sometimes this, but not for this cause that's bad. Use these things for the other stuff, except for when your doing it this way, then do it the other way but not that way because that's bad. Got it? Cool. I hope everyone does it the right way now!!
Listen man, I'm just the messenger 😅
It reads like a comedy skit
It's time for react to die. Can't believe use effect gets called twice on every render in react 18? !remindme to tell my teammates not to "upgrade" from 17. Also remind me to look for teams that use svelte in my next job
I absolutely second this.
@@xiaokourou in dev mode react components render twice on react 16/17 without a fuking log...
It just seemed to me that the talk is a veiled dissatisfaction with React due to misunderstanding than a real problem with useEffect?
The useEffect + useRef combo seems like a pretty good solution. I'd just wrap that logic in a custom useOnMountEffect hook as a drop in replacement for on-mount useEffect usages and call it a day. Putting side effect in event handlers when possible also seems like a good direction to go.
I can still replace it with useMemo or useCallback
@@vijay_rajarathinam How?
this combo still couldn't do anything in the first run, still double call :(
it's not
The reason for R.18 double-effects were not to "get rid of useEffect", but to show developers, that they don't do proper cleanup, or make some other mistakes
So yeah, even tho video makes some good points, but it comes down to "don't use useEffect, use this 9000+ wrappers around it, so you don't have to think"
Still it's not gonna hurt you, to actually know how useEffect works, even if it's a good idea to have it as part of custom hook and use that hook instead
Someone needs to tell him that the square and curved brackets/parenthesis look exactly the same in this font.
bad fonts like this should cease to exist
I prefer to keep with useEffect, this presentation is like a creepy movie that turned useEffect solution into a Fred Kruger of state sync, the simple is better 👍
Someone is always trying to build the perfect solution. But perfection is fragile and complex. Keep it simple, maybe not 100% efficient, but flexible and familiar to all.
Interesting talk, I don't personally have any issues with useEffect, in fact I think the combo with custom hooks is a fantastic paradigm.
The examples given seemed contrived or explained in a way that presents them as overly complex. I'd say that most logic can be abstracted to custom hooks anyway if the code becomes too cumbersome or ugly.
So I wasn't convinced but I enjoyed the talk none the less.
Feel the same way...
Most of the time, the naive solutions will work. But sometimes you might experience unexpected behavior which is what React.StrictMode in v18 is trying to reveal. Working on a large codebase using classic libraries like Redux and having experience with newer concepts can open the mind and give tools to create a better code. That's what we all are trying to do, right.
Doesn't abstracting this just move the issue to a different place? This isn't about components having too much code in useEffect, it's about useEffect being misused. Moving this useEffect outside the component doesn't solve the issue.
@@tvujtatata agreed, but it's how you go about making the argument. If you need to give contrived examples that can easily fixed be with the "naive" tooling, then you have to question the need for a different solution in the first place.
@@rand0mtv660 yeah this video is also missing an actual usable solution
I've been using this technique for 2 years and it really cuts down on unnecessary rendering. Very good to hear this from a senior developer in the community, as it has already been discouraged from working this way by more senior developers on my team saying it was a misuse. I've always believed that it's a way of working with react that brings good performance to the application. Now I'm more confident in using it and I'll keep looking to improve every day! Thanks for the content!
26 minutes talk, yet only described a problem of useEffect that is written in the docs, just called to do something, no real solution, nothing
I could present a masters degree project twice in 26 mins
And the talk is complete mess jumping from topic to topic
My brother in Christ, what is that font?
yeah I was like: wth why squared brackets? o no wait...
I don't understand how useEffect + useRef escape hatch works if React does unmount + remount. The ref should also be re-initialized to "false" when you unmount a component, so it will be false.
Unless, React 18 StrictMode or concurrency logic does a different unmount-remount logic ( lets call it shallow-remount :D ). If you unmount a component useState, useRef etc. everything inside a component should reset.
Am I the only one getting the angular vibe from this guy?
Declarative vs Imperative definitions given in this video are COMPLETELY the same, but one of which is defined with fine words. On the other hand, the scenarios set in this video are how newly react developers would intuitively use the useEffect hook.
Yeah, why not learn the hard way by reinventing the wheel.
Before there was React, there was a certain language called Elm, which came with something called The Elm Architecture (TEA). In TEA, the main building block was a component, which consisted of four functions: init, view, subscription and update (the reducer). They were all pure functions (Elm is a pure functional language so every function is pure there anyway). And guess what? The reducer’s signature was (msg, state) -> (state, effect). In TEA everything composed: views, reducers, actions, inits, effects and subscriptions, which made TEA a fractal architecture where components were just compositions of other components and the application was just the top level component.
Then came Redux about, which was just a bastardized version of TEA, where init was squashed into the reducer and only views and reducers composed and actions were flattened. But it had a dedicated place for side effects in the middleware - a similar concept to subscriptions in TEA. Because of the flat actions, Redux applications were very much monoliths - you couldn’t just take a component with its logic and use it in some other project.
Then came Redux Toolkit about with a crusade against boilerplate and squashed the reducer composition to one level only, making it even more monolithic. But at least they still stuck with the idea that views and reducers should be pure.
But the React community hated Redux and concepts like higher ordered functions. So the React team decided to come up with something simple, which everyone would love - hooks. What’s there not to love? The examples look so simple, there are no classes and no boilerplate right? Except that in real-life React projects, each component now starts with a long wall of hooks code which is mainly dealing with no simpler problem than cache invalidation. With hooks, React squashed the three layers of MVC into a single mess. Adding a hook to a component makes it a dirty function. Because of this, they even had to rename the FunctionalComponent TypeScript type to just FunctionComponent. Now if functions are pure, you can compose, memoize, parallelize and compose them effortlessly. Good luck doing that with your dirty hooked components. With hooks React kissed functional programming a final goodbye. And now, they seem to have made the full circle back to ELMs (msg, state) -> (state, effect).
I feel like I was teleported 15 years back, to the good old days when everything in frontend was nicely tightly coupled together and I would never believe that I would be contemplating switching back to Angular.
Great Presentation David. I really enjoyed the talk.
I cant keep doing this. After watching the video I just want to quit React. Just when you get used to something they change it and now you have to use it in more convoluted way. How is this a good framework? How is it possible that in year 2022 we still cannot figure out this basic concepts for the framework? Idk, but there must be a better way.
... wat? why does React have to be so complicated. When he talks about what we should do instead of useEffect he whips out this enormous useCallback reducer contraption and my brain just melted. Vue is so much easier
I am loving vue 3 after finally fleeing react. amazing architecture, fast, small, a unified suite of dx-centered tools. I'm getting so much more mileage from the time I put into learning my JS framework than with react. vue's reactivity system is a bit tough to wrap your head around sometimes, but in the end I'm always surprised by how few limitations there are and how it all just works. state management in vue is dead simple. CSS is dead simple. installing tailwind is a breeze. granted the changes from vue 2 to 3, and even some changing syntax in 3, put off some people but it has stabilized and is super composable like react and its custom hooks. vue education is also amazing. I could go on and on...I also think svelte is great, and gave solid J's a try. react IMHO doesn't have a bright future...
@@dannydances3568 agreed, unless they implement some drastic changes as Vue did between 2 and 3
Right!? The solution was worse than the problem.
I really wish Vue was so much easier... I've heard that line before and after 2 years with Vue, feeling really let down by that promise...
@@baka_baca which part of Vue do you find complicated or that needs improving?
That font made it extremely hard to read that code
useEffect are like "triggers" in the SC map editor. Whenever certain conditions are met (i.e.: the exectution makes it past whatever `if-return-statements` you put at the beginning of your useEffect), perform the specified action.
The dependency array is simply whatever you are testing against inside your useEffect
Recently, when I was writing nextjs, I didn't know why I ran useEffect development twice. I even manually used ref to judge the mount condition and realized useDidUpdate, and then replaced it with effect during production. I didn't expect that it was react18 strictmode's problem. Oh, my God.
It's not a problem, it's a heuristics that supposed to help detecting problems with upcoming concurrent features.
Nice talk though most examples were just incomplete, important parts of code were missing. I wanted to see a real example and a full implementation how useEffect and/or react-query is replaced with the mentioned approach.
100%, this was my biggest issue with the talk too
Hard to fit into 25 minutes, sorry!
@@davidkhourshid4450 First you are telling us that we all do it wrong and even you as a pro, that it's hard to master. I expect then that you come with the right solution and how to replace it.
Now, I still don't know more than before just that I am really sure that I am doing data fetching and useEffect and react-query still not the right way.
@@faraonch You can't expect him to explain both the problem and a complete solution in a 25 minute talk. Every solution starts with the problem and if you're convinced or at least curious about whether useEffect is a problem, then he's done his job in this talk. Unfortunately, the nature of these talks, due to the time limitation, is just to spark interest instead of giving you instant enlightenment. You'll just have to do your own digging by reading articles/docs or experimenting with using XState yourself. Ultimately, the best way to be convinced is to try it yourself and form your own opinion.
@@faraonch Apologies if this comes across kind of dickish it isn't my intent, but I can't find a better way to communicate the point. Just know that I understand your frustration.
Two main things. One being if you can't grep the next steps from this talk I'd encourage you to explore Suspense more and how it is implemented iunder the hood in React and how user-land libraries integrate with it. React Query can integrate with suspense just fine it just isn't the default.
Secondly, this really isn't about right vs. wrong and too often things get presented this way (I don't think this is how David was presenting it personally). Right or Wrong is highly subjective to the use case and the project. If you and your team haven't felt any issues with the way you are using useEffect and can onboard new team members and have them operating efficiently in what you consider a reasonable amount of time then there is no reason to do something different when what you have already works well. Don't solve problems that don't exist. At a certain threshold though these things do become problematic and when you are operating at that level of complexity or scale the "right solution" and "how to replace it" is largely a factor of your application and the skillset of your team.
tl;dr the *right way* is the way that works for your team and allows you to be productive and have low friction. If you aren't part of a team yet and are aspiring then don't worry about having this answer. Understand there are pros/cons to different approaches and why someone might chose to things one way vs another. That's all.
Interesting talk, I haven't encountered this problem that much. What types of state changes do you guys and galls do with useEffect? For me it usually is to "sync with some external data" in other words fetch().
Ever tried react Query? You are welcome.
@@rohitbbhs007 I do use it a lot of the time, so the amount of useEffect usage is kind of going down these days.
But reactQuery isn't always a perfect fit
@@rohitbbhs007 He asked what the problem is, not what the solutions are. Which is funny because you offered him an answer without understanding his question.
@@invictuz4803 Too much use of StackOverflow does that.😅
Why to do the useRef tool if strict mode rerender only happens during development?
The submit form is not a very good example though.
It explained what useeffect is intended for but not what we should actually be using in more intermediate scenarios where things don't rely on HTML directly.
Great talk! Thanks!
These types of talks highlight just how needlessly complicated and confusing react is. Makes me want to move to using Svelte or Vue.
yeah, it's funny how react is a mystery until someone from core team explain things cos the docs are useless. You know we have hooks for 3 years now and only now the bam abrambov explains that useEFFECT is for ... synchronization.
SolidJS is also worth looking at. It's amazing to see a similar API, but without the need of dependency arrays.
@@izy931 haha that's great
@@HoNow222 is shitty for us, the developers, because learning react is like learning black magic, everything was recommended a year ago in the current year becomes bad practices and the API always changes
There was a kind of big talking point in this presentation that mentioned that useEffect runs twice in Strict mode, while I knew this I thought this only happened in development, once in production it wouldn't run twice. Am I wrong here or you did know this as well and didn't mention it in the presentation?
As I’m aware it doesn’t run in production.
yes, you are right. it won't run at production twice.
@@zigang93 then it's just a waste of time and resources going through so much trouble for something than the end user won't even notice
@@leobaron5934 yes! I went from "omfg" to "anyway" as soon as I realized that extra render only happens in development and there's a nice two line solution if you don't want that. I feel like the purpose of this video is make react look bad and looking at the comment section it worked.
@@EvertJunior well, since I made this comment I have investigated further into this subject, and while the double useEffect does happen always in development, it is done to spot potential problems with your code, so basically the double render is forcing something that could actually happen in production, not 100% of the times like in dev but can happen nonetheless, therefore I think this video is an introduction to what future react could become
I learned React with class based components and enjoyed it because it was really easy to read and understand. Coming to useEffect has always felt like a huge step backwards and seeing all these awkward ways of handling it kind of confirms this for me. I miss the good ole days of being able to easily understand the code and the main hoop to jump through was binding your methods in the constructor.
Couldn't agree more, I moved to function components because they're supposed to be more pure, easier to test etc. But after a while I have begun to feel like all this fluff to make them work actually introduces more bugs, complexity, and slows down development. Thoughts?
me after 5 hours. I finally have a good grasp of useEffect.literally after 1 minutes this video shows uf
Putting every side effect in useEffect and all data (UI, server, ...) together, e.g. in Redux, is something that slowly deteriorates the codebase. After some time it will be more difficult to get rid of it and also to change the mindset of devs that are used to it. It is good that React team is also explaining the approach to these concepts and new libraries like Relay exploring it. I guess this overuse of the effect hook is caused by switching from the Class components and treating the functional ones the same. Even if you split separated effects.
Great explanation and great talk. I learned a lot!
Thanks David!
Bro... Why would you pick a font where parenthesis look the same as brackets ?
how did this framework became so popular is beyond me
lmao i'm wondering the same thing. how are people using this hogwash? it's utter insanity, masses of devs literally brainwashed by this paradigm
@@bribes_for_nouns Yea I know.. honestly now that js supports modules you might be better off writing vanilla js instead of using React
what about your own custom web components? it seems like web components always get a bad reputation because of SEO but is that the only reason
the biggest thing React has going for it is everything being backwards compatible out of the box without thinking
I've seen a few people swear by the useEffect hook and say that it's a must for every react project. I'm still learning react but thus far, I also haven't really found this hook useful. There are so many other ways to do the stuff you'd need to do with useEffect that it's not as useful as I initially thought
lol.
Very nice talk!
Suspense for data fetching still not in official react docs. Is safe to use with tools like react-query and useSWR?
Have you using it in production apps?
Thanks
You can also use both Suspense and tools like React Query or SWR to fully optimize the performance in production
I’ve been using react + mobx for years so luckily I have barely had to touch useEffect. I never found it very intuitive and it seems I’m not the only one. Creating abstract stores really helps you keep the view just a representation of data and all business logic in a testable stand alone class without dependencies on the views / react.
Why mobx over context API?
@@David-rz4vc computed values, reactions and overall support for a full-blown data model.
@@David-rz4vc I don’t believe the context API has all the features I use of mobx such as observable, computed, autorun. With all these tools I can keep all logic in a view model and keep the components purely views.
What do you use instead, just autorun everywhere? And then use global state even when only a few components use them? No useEffect for UI state changes anywhere? I just moved to Mobx but still find myself using Context API for component tree state and useEffect to update those.
@@GenghisD0ng no, rarely need useEffect. Any component that relies on mobx state is an observer and thus will update when the state changes. Have a look at the mobx docs and perhaps a TODO list made with mobx and react. It’s all fairly simple, or should be if you’re using it correctly. Hope that helps!
react-query one love
I didn't know that devs struggle with useEffect 🤔
I’ve been writing React since 2016 and I’ve never had an issue lol. My feeling is that it’s mainly newcomers complaining and don’t understand the complexity of the problem that react hooks solves.
@@proletar-ian Same. In fact I've felt like simple, clear coordination of useState and useEffect has felt like a very very nice simple declarative way to write code. It seems like this talk is a solution in search of a problem.
Same.. never had issues…
Perhaps an unpopular opinion, but I prefer not to bring along a 3rd party state management library... or if I must, I prefer something very simple like recoil. I also have had amazing luck with react-query, and would be curious about the difference with rendering as you fetch instead of fetching on load or whatever.
React people, please look into using RxJS as an event bus. It'll solve so many of your problems. David Khourshid is completely right, side effects should happen outside of your component. It's a bad idea to have side effects in your event handlers, you will regret it in the long run. The event handler should only handle the event in the desired way.
I would never start a new project with react again. it only keeps getting worse
great video thanks.
The (state, action) => ({nextState, effects}) pattern reminds me a lot of Elm, only Elm was written with that pattern in mind
I love Elm!
@@BivinityPeng I've tried it once or twice, but never made it into a functioning application. I've certainly liked what I've seen. What sort of experience do you have with it?
It’s a reducer, it’s used in a lot of places including useReducer and redux
It sounds all nice and all but tbh it might add unnecessary complexity to an already complex project. I'm not a big fan of useEffect but at least gives developers a better understanding on what's going on.
A better understanding compared to what approach?
15:29 that reminds me a lot of Elm's update function
the whole js ecosystem has made things so opinionated that im afraid to write vanilla js for basic apps now coz im too much into frameworks, Such talks make me realise that we should be dependent on frameworks and try to find our own solutions to the problems we are facing
Amazing speach!!! I love it very much, as i feel the paing handling effects in useEffect 👍👍👍
Strict mode will only run effects twice not in prod. It's a dev tool.
Yeah people have no idea what useEffect semantics are. xState has nothing to do with useEffect
Thanks for speaking up about the most common pain point of us React users!
I think this is a bad approach, you're taking a simple concept where effects happen as a result of state, and changing it so that effects happen as a result of a change of state. Definitely introducing more code paths and component meta-states for no real improvement.
Yeah seems like the only real issue this would solve is actions such as data fetching. Which as he mentioned have already been solved by either using a useEffect on mount (using the ref approach) or in an event function (e.g. onSubmit). But it’s hard to really know what he was trying to suggest since, as other comments have pointed out, this talk lacks any complete examples
Which came first, chicken or egg
It's same, you can either start with state first or event first approach.
An event will trigger state change and populate state or and external store would change state and trigger render.
Just don't mix states and events and you are always good to go. Events trigger transitions and they can happen inside or outside of the component depending on usecase and not all usecases are going to be same
TLDR; you dont want state loops where you have to determine if state should change inside useEffect function of not. That will prevent lots of headche that comes with dependency graphs and automated rendering trigger of react.
Basically with useEffect you will have a component state mapped and dependency mapped, so that react knows when to check state when one of dependency changes and execute rendering pre process which will populate new state and trigger render.
Problem is framework like react doesn't separate concerns and slams everything inside single component like function programming which makes it harder for beginners to understand what function is supposed to do and they mix responsibilities.
At the end you don't want to use any events or data manipulation inside useEffect as it will definitely trigger function again, that's by design and you will have to stop propagation manually by termination condition. It's not good practice and should be avoided, instead use lifecycle hooks to initialize, populate and update states and avoid unnecessary code paths that cause side effects.
dang this dude gave a talk on React *outside*
better man than I
parentheses look like square brackets and that's super confusing :)
If we need videos like this to explain a core, well documented concept in React, then there is something wrong with React. Can’t wait for Solid and Svelte to become more mature and get all the library support I need to switch.
Preach!
So then where do you put things that u want to happen on Mount? Do you use class component at that point?
In spite of all the hate, this is actually a pretty good talk
Usage of square brackets instead of circle ones is making me lose my mind
I think there is a race condition at 21:07, using useRef with useEffect part. When there is 2 successive calls to useEffect they both may run concurrently before one finds a chance to change the useRef. And with everything else going on that may be more difficult to debug.
So instead of that isn't it better to just use regular useEffect and knowing that double render issue will not happen in production, because strict mode is dev only. I'm a React beginner just asking to learn better.
You need to remember this is JavaScript at the end of the day - it's single threaded and not preemptive. Once the effect function is called, it will run fully (as long as you haven't marked the function async and you're not doing async-await in there) before other code has a chance to run, with no risk of a race condition. If you are, avoid marking the effect async and instead create an inner async function (I personally like making the first .then on a promise an async function for this case), that way the flag will still be set synchronously while the rest of your effect happens asynchronously.
Double render is not just a strict mode thing - strict mode will force a double render, but it can still happen due to concurrent rendering in production, and it will result in some extremely difficult to debug issues if you don't run strict mode when developing.
@@SlackerVez Thanks for the reply. But I'm still confused a little bit. I read somewhere that useEffect runs asynchronously and non-blocking. And you said when you fire the useEffect it will go ahead and run from top to bottom. Now, let's say we got 2 useEffect running back to back and doing some expensive computation in doSomething() function as in 21:07. In that case both useEffects will run because useRef is still false. Am I missing something? Also can you confirm that, when useEffect runs it runs on the event loop(que) asynchronously, right?
@@derdere7803 Yes, useEffect does run asynchronously and doesn't block the render function, but I wouldn't call it non-blocking. React runs through the render function, queuing up the effects to run later (when and how many times is up to React's scheduler, the effects are not invoked directly by the event loop), however, once one of the effect functions is triggered, the function supplied to useEffect will run through top to bottom, synchronously (it has no choice, JavaScript does not have "real" concurrency, so it has to wait. Control flow can only be taken back at key points like "await" and "yield" statements, or once the function is completed). Assuming a non-async function was passed into useEffect, you can look at it as an atomic operation, there is no way for any other code to execute before both checking the flag and then setting it at the end (setting the value on a ref is synchronous and the change is immediately visible). Putting an infinite loop into useEffect (i.e. a simple "while(true);" ) will freeze your window, so, again, I wouldn't call it non-blocking, it just blocks at some point after the render function ends (but before the (re-)rendered component gets displayed).
So basically:
1. React runs your render function. Effects are registered but not executed.
2. At some point in the future, React calls the supplied functions *one at a time*, as there's no "real" concurrency in the language. At no point will two effects run at the actual same time unless you explicitly do async things.
Note on async things. React does not wait for a returned promise to resolve, so an async function passed to useEffect is considered finished when it reaches the first "await". With those you may get an illusion of concurrency, but alas, it's just a somewhat convincing fake, and it's one created by the JavaScript engine and not really specific to React (after the await, your async functions will get called from the engine's event loop, rather than React's scheduler). You can still guarantee that everything between two "await" statements in an async function will run in a single go, and you can still apply a similar pattern as displayed at the time stamp, you just need to rearrange it so both the check and updating the ref happens before you call your async APIs.
And a final note, you can have multiple threads in JavaScript (through Web Workers) and so you can have true concurrency, but due to the language's design, the workers can not share variables with the main thread or other workers, they can only communicate through messages, so even in that case your ref is safe from outside manipulation.
It's late and I've spent too much time typing it, but hopefully it clears some things up :)
@@SlackerVez wow, such a great answer. Wish I could thumbs up more than once. Finally, I get my head around it. And the keyword for me in your answer was the “atomic”. It finally clicked. I was reading an article about web workers just before your answer. And now it makes more sense. Thanks a lot for straightening it up.
@@SlackerVez As someone who is also up late and just spent too much time typing up a response to someone else, this is a really good answer. To add a small bit on to this, you actually *can* share memory between web workers and an app in browser and similarly with worker threads in node using ArrayBuffers, but those use cases are pretty niche.
Great talk! Thanks, David!
Where can I read more about this topic? Thank you.
use effects is less challenging than this speaker is
+
I thought it was my problem that can't understand why he is saying 60% of time, turned out it's not.
Awesome!
You can't force the reality to follow expectation, just let expectation follows reality. This is why react functional component with useEffect is more popular than class one
In the Angular world NGRX Effects handle all of this. I wish there was something equivalent in React/Next
Oh, I already do this!
Thanks for this video!
I use effects for quite a while already. Probably around a year.
However, the concept still doesn't feel intuitive to me.
Probably this is because I haven't invested enough time to actually understand the underlying concepts and correct design pricnciples. But it also could be that the API is a bit hard to comprehend.
Simply put, this API is hell and people accept it simply because it is made by react. Any developer/library that would do the same kind of mess would be yeeted. Just try it, create a function that will send a mail if you pass an array, send a text of you pass a boolean and log if you don’t pass anything, call it doSomething and check your collegues reaction
I think the key is to stop make front end so complex for the kick and start scraping layers of unnecessary techs and “pseudo problem solving” and rethink basics and the needs of most websites.
it's getting ridiculous. I remember people saying front end was finally slowing down... every fucking week it's just more and more shit. i'm so sick of it. I enjoy learning but not when it's the literal 80th way to do the same fucking thing. over . and. over
i think youtube can read my mind, and has the right content for it too
I see everyone talking about react query but why not use redux toolkit that has the same functionality?
Redux is old
It is overcomplicated and no one knows how to use it in correct way :)
Always, when I see redux, it is a tone of reducers disconnected with real world, that do strange things for no one knows stuff.
@@David-rz4vc I wouldn’t recommend redux on its own in this day and age, but Redux Toolkit is phenomenal
@@David-rz4vc Most things in programming are, that's not an argument unless you're just looking for the shiny new thing. Redux toolkit is a decent option, it takes out all of the boilerplate of that old Redux you mentioned and it's pretty intuitive.
@@David-rz4vc Probably you don't understand what is software development.
Redux is a tool, library, convention and implementation of a flux architecture.
Tools choice should be driven by efficiency, but not an "age".
Event-driven architecture exists for decades, but we are still using it.
Does it really have to be that complex?
fantastic talk
*really* poor choice of font for those parenthesis. how did anyone let him present like that?
there parentheses look like brackets and it's making me nervous haha
I’m suddenly very aware of how much Kent I’ve been watching that I can identify his voice from the audience 😅
So we are stuck with the code-behind model?
I use useEffect for like everything to avoid code running more times than needing and have never had any problems. When something outside changes, my code adjusts to include that change.
This is the case where the cure is worse than the disease. Sagas, redux, another state convolution - these are not great ways to reason about code. We need better conceptual primitives.
the more i learn about React the more i want to get back to Svelte...
@no1youknowz my company uses react. thank you for advice though. its golden. very useful.
@@MichaKurzewski Understandable. React dominates the market!!
My laptop crashes and forcefully shut it down to start again . use effect has been a nightmare .
Comon guys I just finalized to learn how to use useEffect and now is gone?
It’s not going anywhere lol this talk is a joke
I just started using useEffect() to handle graphql data, is this a wrong approach?
Alternate title: useEffect needs to be stopped
Learning react became lately like learning black magic, everything was recommended a year ago, in the current year becomes bad practices and the API always changes.
I hope one day Dan Abramov finally resigns so things go back to normal like previously. People should use their brain before making major changes not just be driven by hype.
the whole js ecosystem is a clusterfuck that makes me want to cry everyday i wake up
Most often and not all, devs are just creating too much state thinking that’s the only way you make a reactive data. And putting all those into a useEffect makes it more confusing.
I left more confused than when I arrived. React, what the hell
this speech makes me feel like i'm in a mental asylum
Looking at all the weird ways even senior devs use react hooks, I feel like they have provided us with hammers and wrenches where we actually needed scalpels and needles, or the other way around idk. Everyone has a new interpretation of what each hook does.
Anyway isn't this th-cam.com/video/HPoC-k7Rxwo/w-d-xo.html what useQuery and useSWR do?
Wait so how does this new store hook differ from using redux or even something like the useContext for a smaller app? Why did they even make this hook what was the reason?
if you're talking about useSyncExternalStorage, I think he says that's it's not new and that Redux actually uses it under the hood. I don't really understand it, but I guess it's useful for global state.
I am also confused too
LMAO is useSyncExternalStorage actually a hook? omfg i'm dying
At this point I am very confused. I may move to Vue since it has very clear life cycle hooks
unfortunately the Vue library ecosystem is at a crossroads because Vue 3 was heavily influenced by React Hooks. quite a few popular Vue third party libraries don't support V3 fully yet.
Why is he using this weird font? I can't distinguish parenthesis and square brackets.
this is the remaining on going issue with React, where developers have to find a new way to not mess the code around. It should be the other way around, developers should worry only to create the product, not the hack for the framework for the product.
Because lifecycles were "hard" to handle, blaming the classes components as well, they invented hooks, cause function (to note NOT functional) components are better (why, aren't classes just a set of functions encapsulated ?!). So Hooks add the "lifecycles" in functional component but why, you think this will save you from spaghettification? nope.
Just extend the reducer hook to dispatch side effects Elm-style
Msg -> (Model, Cmd Msg)
why not adding actual life cycle hooks in recat...
Or just use class components!
@@NphiniT no... i'd rather use useEffect. i absolutely fucking hated working with class components!
@@whoman7489 I loved it. Also, I don't know how to explain react components' life cycle without using class components (I used to teach React)
@@NphiniT only if functional components had error boundries and life cycle hooks then there would never be a need to use class components!
@@whoman7489 Agreed. I just don't get the recent hatred against Object Oriented Programming in general
Senior React devs struggle with useEffect?? Huh?? I seriously doubt that. People will post whatever just for social media engagement. If you're a senior react dev struggling with the concept of useEffect (a very very common hook in modern React) then you're not a senior react dev..
I've taught numerous React Training workshops and have been building React apps ever since it was announced. I still struggle, especially with the React 18 changes. Keep your misplaced ego to yourself.
@@davidkhourshid4450 my comment is not ego based. I’m going on 6 YOE with React. As hooks became the best practice, I have never seen a senior dev struggle on the job with useEffect. I’m sorry, it’s just not something I’ve ever seen be a problem. As I said - I think people post sensational things to social media to stir up engagement. Tweeting that a senior dev struggles with one of the core hooks in modern React is out of left field and just stirs the pot.
there's no senior react dev out of the core team bro
I've been using react for a week now.
And it's okayish but clearly the React library developers are a bunch of palookahs. Because all the weird ass react terminology that doesn't have anything to do with the actual function.
@@davidkhourshid4450 Calling someone out for having a different experience is a bit unnecessary and not very productive. While I agree that the useEffect api is clunky and a bit limited, most people I have worked with use it to "sync with external data". But perhaps we are writing very different applications for different purposes.
Getting strange behaviour from componentDidUpdate/componentDidMount was definitely possible too, even if the api was a lot clearer.
I realize that I am still a beginner because I did not get any of the things he said
Really would be interesting to see how many commenters were employed engineers, and of those who are employed who works in a team with more than a handful of people. Think David gave a fantastic talk wish I could have been there this year.
Error at line 4
>>> 'handful' undefined
People forget that react is supposed to help you not make life more complicated.
When it doesn't and you need to introduce all kinds of helper libraries just to handle simple use cases it is probably better to use another developer experience framework