Check out my new course called Next Level Next.js! A full stack course covering GraphQL, TypeScript, Apollo, Prisma, Mapbox, Auth and lots more! courses.leighhalliday.com/next-level-next-js Is the cost prohibitive? Hit me up on Twitter (twitter.com/leighchalliday) and I'll get you a Purchase Price Parity coupon code. Same goes for students.
someone give this fellow Canadian a Nobel price for "clarity of explanation". clear concise and so well explained... Bravo!!! I wish I had seen this video months ago...
There was nothing new in this video for me, but I loved watching it anyway! This presentation was very well executed and i'm excited to see what you come up with in the future. Good job!
yeah same, I love going back to the fundamentals after I did a deep dive of learning and had some experience under my belt. You almost get a new sense of confidence and reinforcement. I already said this but Leigh, your teaching style is really really good!
Thanks for this! Finally clarified my confusion as to what I should to when trying to pass state between components... I didn't know that was referred to as "lifting state". Thanks!
This video should be see it by all React Developers. Few people are talking about ways of state management. I love your content (: Grettings from México!
@@leighhalliday I think you're mistaken here. Every component, that uses context (via useContext) will be rerendered as far as the context's value is changed. Another thing i'd like to mention is that usage of context makes your code more difficult to test. The Law of Leaky Abstractions term is applicable here I think. After you provide context and your component consumes it - you have to look into your black box because inputs are not the props anymore. Please, give some feedback about this
This was really an outstanding video. it seems others have addressed each of these use cases in isolation but I have yet to come across something as clear and comprehensive. Thank you!
I really really like the pace of your tutorials Leigh! You really have a gift for explaining things and keep people interested. Looking after more content from you!
Another very helpful explanation. I really like the reasoning behind the decisions made or the options chosen. (Yes, I'm a fan of your style of video's)
Recently discovered this simple library called "Simpler State" on Hacker News. I'm currently playing with it... feels like using Context but without Providers. So far looking super simple for the "global state" step you talked about. For Redux, I also like the "Easy Peasy" lib. Nice tutorial btw!
So good! If you can, maybe next time include a Github Repo so your viewers can code along. Not necessary, but it'd be nice to be able to code with you. Anyways, great Video!
I came here from a Reddit thread, I loved how you explain every single thing with utmost accuracy. 💙 One more thing, what are the specific use cases for React query? Can't we just handle that with axios and promises?
Thanks Tulsi! Think of React Query like a wrapper around Axios + Promises (or fetch)... it handles: when to fetch new data, caching, loading state, error states, etc... you can totally combine Axios with React Query.
Great video !!! Learned a lot in just 17 min !!! The one question I have is what is the difference between useEffect and useQuery if both are executed when a certain value changes. Thank you again
Hey Tibeb, thank you! useEffect is more general purpose helps you to execute a side effect when a key changes, which could totally be used to load data. useQuery also runs when key changes, but it is specific to loading data, and handles loading state, error state, caching, re-load on focus, etc, etc... it provides a ton of functionality that you would have to build yourself.
I've been using this pattern since context API came out, glad to see I'm not alone, was having an argument with some other devs a while ago about not defaulting to REDUX/MOBx when this is available natively
@@leighhalliday For sure, I just mean a lot of devs go straight to using redux or mobx even for the most simple app state management because it's what they're used to. Those libraries definitely still have their place.
Well done. Great explanation and thorough example. I'd like to see more on context provider though, you didn't mention the default value you passed ("CA"). How would you load that from a fetch call (if you wanted/needed to) for example.
Great and clear video. I have one question. In the case of react query, use query returns data, status, error. Is it Okey to store in global state so that I dont have to prop drill the data status or errors. By using this take away the advantage of react query. Do caching and everything still works the same way?
If I have more than 5/6 contexts in my app is it time to switch to Redux to take advantage of a central store. My workflow is using context api with hooks like useReducer, but having multiple providers for each context seems slightly messy.
Let's say you have some global value like so passed through context: { admin: false, fname: "Jon", lname: "Law" } Let's say the user changes their name to Sam . How would you prevent unnecessary rerenders? This context contains no additional info to split into another context (like an array of movies). The problem with useContext is it subscribes to all changes of value instead of a single key. So first is the issue of optimizing you updater functions in your value with useCallback like setFName for example. Calling setFName would otherwise create a new setFName function based on the fname and trigger a context update and rerenders to all observers that useContext. Furthermore a ProtectedRoute will rerender on setFName although it only cares about the admin key. So how do you address these issues with context?
Hey Malik! You're right there might be unnecessary renders, but honestly for something like this that isn't updating frequently, I wouldn't worry about it that much. If you are having performance issues, you may want to check out Recoil which solves this sort of problem.
Thanks, for such a good video Leigh. I was wondering how do you manage state if we have multiple react app build separately then deploy to the server but using the same router. For example, I am going to home/app1 click a button that should transfer data to my home/app2? I wasn't very clear on this. Cheers man
Hey James! I am honestly not sure of the best approach for sharing state between React apps... maybe through a shared auth token with a backend? Or localStorage? Or through query params?
Thanks for the great explanation! Just wondering whether you consider it useful to attempt to maintain state 'as close to the component that needs it' IRL? Or do you tend to pull most state that needs to be used elsewhere out into global state by default? Do you actually ever do prop drilling these days? For example I'm working on something where there's one component that's fed by props from the parent, but pretty much everything else is using global state. Even though I could probably use prop drilling to pass the relevant state around, (components aren't deeply nested), I think I find context and global state a bit simpler to reason about.
I love all of your videos in relation to React, couldn't be more straight forward and informative at the same time. Can I ask, when wrapping the HomeContent component in memo() for the purpose of only triggering re-renders on prop changes, are there any cons to using memo()? And if not, would there be any reason to not wrap all components with memo()? (I appreciate there's probably no need if the component doesn't change prop's state but is there any performance cons to memo for example?
Hey Iain! I would just let React take care of when to re-render 99% of the time on its own... it'd make your code more complicated for something that might not even help with performance. In this case though it was special because it is the direct child of the context provider... want to avoid it re-rendering any time the state changes.
Hi, thank you for the video. But I found this in the official doc. “React.memo only checks for prop changes. If your function component wrapped in React.memo has a useState or useContext Hook in its implementation, it will still rerender when state or context change” and I am a little confused
Hey Carlos! That's actually exactly what I wanted it for. There are no props being passed to it, so it should never re-render unless its internal state changes. Without memo it was re-rendering every time its parent (the context provider) changed.
Hey Hasan! I think I would always start with this way: - Local state (useState) - Lift state (still useState but in parent component) - Global state (useContext) - If this is not enough, investigate something like MobX
Ciao Leigh, Provider is smart enough and re-renders only children components that actually consume the context. In this particular case you don't need memo.
Yes. Behind the scenes it does some complex caching so that if another component needs the 'CA' data and it's already fetched it once before, it will know to reuse it, depending on the cache policy you've set, or re-fetch it if the cache is stale. All of those external data libraries have some version of this and it's really cool! No more fussing with redux sagas or thunks, or managing loading states or any of that stuff.
Hey Sahas! Sorry... I don't think I have a public one to share. But, I do have a course where we have both global state with context and server state with Apollo Client (GraphQL). You may want to check it out! courses.leighhalliday.com/next-level-next-js
also Im not sure if you have made video about that but it would be great to see how you manage renewing the tokens or overall the whole authorization part
Hey Lex! It just arrives as props to your page, so you could probably use the prop value from the page as the initial value in your context and then share it that way.
Would you but external state from react query into a context or would you extract it from react query in components lower lower down that needs to read part of the data.
I guess it totally depends where I need the data... I don't think there is a universal answer. In a context could be a good way to make it universal in your app.
@@leighhalliday Before You Use Context Context is primarily used when some data needs to be accessible by many components at different nesting levels. Apply it sparingly because it makes component reuse more difficult. If you only want to avoid passing some props through many levels, component composition is often a simpler solution than context.
@@leighhalliday When to Use Context Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language. For example, in the code below we manually thread through a “theme” prop in order to style the Button component:
Hey Xing! At that point I think you'd have to put it in actual state, because it goes from "server" state to "app" state when you start to edit it. You could use the response from useQuery as the initial value of your state.
sir, whats your opinion about vue? there is so hype around it, especcially about state managment, no need such things like redux, you just change state of component and vue magicly does all thing for you. I allredy learning react, but i really jealos about all of that in vue, and people say that it's one of many features that vue has, what is your vue vs react opinion?
Hey! I haven't really looked into Vue... it looks like it has a great community, but I feel like there are so many things I want to learn in the React community (Redwood!) that I haven't felt the need to go look deeply.
Hey Leigh! I noticed that without the use of 'memo' for HomeContent, HomeContent still isn't being rerendered when the context is changed via button click in CountryPicker. I was wondering if anything changed since this video? I tested it by console.logging within HomeContent before the return.
Question: how could we have a managed state in react-query.. like here execution of fetchCountry is not in our control.. if u had to call it conditionally/onmount then how it could done?
Hey! On mount it would be called automatically, but if you want it to be conditional, I would actually move it to a sub-component which is only rendered if it should actually do the HTTP call. Break the big component into smaller ones... they can even just live in the same file.
Yes, but useQuery has a caching strategy for you to control when it refetches and there is a way to force it to refetch manually as well. Check out their docs for more details.