Finally just managed to watch this all the way through! Brilliant explanation on useState and I've already thought of a place in my own codebase I could benefit from this. Thanks so much. Oh, and thanks for the raffle prize! Very chuffed. 😄
13:37 i dont get whats the difference of ref() and useState() then couldn't i just use ref() inside composable function scope? or ref is only meant on the client, for template 2way binding and initiliazing what was called "data" in vue2 object API ?... not for data per se
If you use ref inside a composable, you have local state and state won’t be shared across usage (as you invoke the function per component, it’ll be state per component)
How do you deal with multiple instances of a component on the same page, each of which should have its own state? For example, consider the following: const count = useState("counter", () => Math.round(Math.random() * 100)); Due to the "counter" key, each instance of the component will get the same value. However, I'd like each instance to have its own random value. Thanks for the videos!
@@TheAlexLichter Thanks for your reply. The catch is that I use this component in many different places, and there's no consistent way to track which instance gets which key. I prefer to keep my components autonomous and not require management of an external key. The application for this might be obvious: ``` ... ``` The problem is keeping `uniqueId` unique for each instance and be SSR compatible. I see hints of a `useId` composable coming to Nuxt. Maybe this is the solution? Or can you think of another way in the meantime?
The useId composable will likely be implemented in Vue 3.5 (as mentioned in the video). Then that should be really easy! Until then, check out Daniel's vue-bind-once github.com/danielroe/vue-bind-once
So how would I manage global state with useState do I create a composable for this and manage the state in that composable? do you have a seperate video on this? I'm sadly a glorified React dev learning vue/nuxt. So the concepts don't click yet.
thanks for the great content Mr Alexander, please if you can make video explaining JS execution/useFetch on server/client like common issues or tips because that confusing sometimes especially in my case where i want to make ecommerce and for example should i fetch the product (singular) on the server for better SEO while the profile page can be ssr false. Thanks Again
One question, i need the page not to render in the source of my ssr page the "NUXT_DATA" script, or if it has to be in the page which is fine, to not include all of my state, is there anything for that? It does not matter if its with pinia or useState, If its a large application it could include a lot of needless things.
Good question! I wouldn't say that it is bad practice overall, but when using nuxt and (one day) switching to SSR, you might run into the issue from above without noticing. Instead I'd go with a more explicit way, e.g. a "globalState" file that exports these `ref`s/`reactive`.
Sometimes you don't know what component is mutating the global state in composable when composable is used in many place, so debuging can become very challenging. But with a very carefull use, it can be very handy for some case.
First of all, excellent videos! I have a problem that I've been stuck on for a while, could you help me? I have a composable called useQuiz, to handle a quiz, its questions, and the options for each question. I would like to manage the state of this quiz with useState in my composable, but I don't know the correct way to store the result of useFetch or useAsyncData in the quiz variable of my composable to manage the state across all child components. Maybe my implementation is not correct, should the result be placed in the onResponse? Or maybe inside the useAsyncData handler?
useFetch already uses useState (more or less) under the hood. If you want to further alter the data, you might have to save it in a new useState indeed. You could watch the result of useFetch. Happy to give better advice with a stackblitz or similar
Awesome video. Been using useState so much in my application; it actually helped me understand WHEN to use Pinia as a state management tool. On a sidenote, may I ask if you would be willing to cover how the wrapper component works in Nuxt? I sometimes get mismatches warnings in my console and I resort using to this component but I never fully understood why and I couldn't find a good answer in the community?
Client-Only "hides" the problem only. I talked about hydration at Vue.js Amsterdam, the talks will be released soon & will link it here. Slides can be found already at github.com/manniL/talk-hydration-vuejs-amsterdam-2024
Alexander, I have multiple frontend projects that merge into one using a Nuxt layer. I need a unified state management solution for these projects. For example, one UI manages robot jobs, while another displays job reports. What would you advise for more generic store mechanism? How can I integrate useFetch with state management, considering useFetch is typically used only starting points of component or composable? I feel like if I use state management, I will have to give up useFetch.
Just use an actual database at that point. Or simply Redis. You can use Nuxt's server side API endpoints feature instead of a separate backend application. These endpoints can query your Redis. You'll have to either make the users create accounts or store a randomly created ID in the browser cookies (assuming all of the apps are on the same domain/origin). You can then use that ID (or username) as the key to query the redis db and have shared state between the apps on the server side, but not shared with other users.
Thanks for the explanation! What should I use instead of useState() if I do not want to create a **global** state? I mean, useState() always needs a key or uses file:line as a key. But what if I need to create an SSR-friendly composable, that should return **new** state (just like a Ref) on each call? Let's say I want useRandom() composable (it's not what I really need, but I think it is a good example to understand the problem). Without SSR I can just use a Ref. useState() needs a key, but I can't generate a key (that will be the same on the server and on the client) as there is nothing I can use as a source data. file:line key is also not suitable here as useState() will be always called from the same file:line (because it is called inside of my composable). Maybe there is a helper/something to generate a key based on a stacktrace of the current call or an other way to solve this? Basically, I need a Ref, but SSR-friendly.
Isn’t it actually better not to provide the key & let nuxt generate it automatically so that there is no way you could get a duplicate key in a large project? The key might make sense if you need to access the state from multiple places in code, however, even then you could just create a wrapper composable around useState without key and call it instead of useState(), couldn’t you?
I'd rather trust my own key (so I definitely won't duplicate it) then on auto-gen 😛 + It is easier to debug in the devtools (which is the better reason here 🤣)
There is a problem. I'm using one component outside layout and one inside layout. Both depends on the same state. When I change the value from inside layout, the value of the component outside layout doesn't update in SSR. // this component doesn't update when the value is changed in layout // the vaule is changed here The problem solves when I use inside layout
That is correct as SSR is "top to bottom" and there is no "real" workaround there I'm afraid. You can't update what is already rendered during SSR. See github.com/nuxt/nuxt/issues/19258 for more details
Thank you 🙏 If you need global state in plain Vue without Pinia, then you *can* go for the pattern from the video: a `ref` outside a composable to keep the global state inside. Can also be a `reactive` object holding global state in a different file that is manipulated!
As far as I understand, useState was created for a very small amount of data to provide an instant access through the project. Once I had an interview with a company which used useState as a main state system for depencies reducung. I failed it because of a different vision of the topic😅 Seems like it’s really supposed to be the Pinia replacement inside Nuxt. But I still believe that useState is a completely different tool (even after your explanation).
@@TheAlexLichter I’ve never tested it properly. My argumentation might be pretty weak but I’ll still try to explain. From my perspective, useState is a global and enhanced version of React’s one. It helps to create small stores that can share needed values between components without extra complexity. I don’t feel that I have a control over data fully as well as I’d do it with Pinia. At the same time, I don’t need to implement useState because I’ve already got Pinia that does the same thing.
@@TheAlexLichter I tried to use useState to store the idToken to make a request with useFetch with Authorization Bearer token but struggled with it for hours until I noticed I should use useCookie for this. It was not clear to me what SSR-friendly means in this case.
@@TheAlexLichter To be honest there is much missing in the docs. Your videos seem to be a natural extension of the (poor) docs of Nuxt 3. I feel like the docs cover 30% of the Nuxt possibilities. But the team seems to be aware of that if they link to your videos in the docs xD Big F to the Nuxt team, Big L for you. :)
Приветствую, Александр. Такой вопрос: в каких случаях следует использовать объявление useState вот так: const nameVar = () => useState('title', () => 'что-то'); а в каких вот так: const nameVar = useState('title', () => 'что-то'); И в чём разница?
Я не думаю, что первый вариант правильный. В видео, где он описывал неправильное использование useFetch эта тема как раз и затрагивается ruclips.net/video/njsGVmcWviY/видео.html Она применима ко всем use+Что-либо приколам нукста (в моём понимании) Применения первого варианта, где const nameVar = () => useState('title', () => 'что-то'); я даже не видел, на самом деле. Есть какой-нибудь пример?
const nameVar = () => useState('title', () => 'что-то'); allows you to decide when you want to initialize the state and get a fresh "ref" (that is populated with the state) all the time. It avoids issues like we've seen in the plugin, where the values would be "shared".
This is fantastic to cover! Love it! Explaining the link to useAsyncData helped me understand useState easily.
Glad it was helpful and happy to hear it closed the gap ✨🎉
Thank you, for the quality content again. PS. Congratulations on your 2k sub 🙌
You are welcome! Glad you enjoy the videos pal 🙏
Onto the next 2k 😛
I really enjoyed your video! It was so clear and detailed, and I thought it was awesome. Keep up the great work!
Thank you so much! 🙌
your video is awesome, it's talked about more details about useState than official weisite,thank you~
Finally just managed to watch this all the way through! Brilliant explanation on useState and I've already thought of a place in my own codebase I could benefit from this. Thanks so much. Oh, and thanks for the raffle prize! Very chuffed. 😄
Thanks a lot 🙌
Looking forward to see you in AMS 🎉🎉🎉
It's a nice explanation and usage. Thank you! I will do it!
Glad to hear that!
Thank you very much for your video's they are really helpful, love them!
You're very welcome! 😊
13:37 i dont get whats the difference of ref() and useState() then
couldn't i just use ref() inside composable function scope?
or ref is only meant on the client, for template 2way binding and initiliazing what was called "data" in vue2 object API ?... not for data per se
If you use ref inside a composable, you have local state and state won’t be shared across usage (as you invoke the function per component, it’ll be state per component)
it's great video Alex produces content for us and it's free
Thank you 🙌
Anothee great video! 👌 tips like this make it much easier for beginner like me to get a comprehensive grasp of how nuxt works under the hood
Glad it was helpful! 🙌
Great explanation! Thank you, Alex
You are welcome 🤗
How do you deal with multiple instances of a component on the same page, each of which should have its own state? For example, consider the following:
const count = useState("counter", () => Math.round(Math.random() * 100));
Due to the "counter" key, each instance of the component will get the same value. However, I'd like each instance to have its own random value.
Thanks for the videos!
Hey Chris! Then you could pass a key for the state as prop (and then prefix it in useState so you fully avoid collisions).
@@TheAlexLichter Thanks for your reply. The catch is that I use this component in many different places, and there's no consistent way to track which instance gets which key. I prefer to keep my components autonomous and not require management of an external key. The application for this might be obvious:
```
...
```
The problem is keeping `uniqueId` unique for each instance and be SSR compatible.
I see hints of a `useId` composable coming to Nuxt. Maybe this is the solution? Or can you think of another way in the meantime?
The useId composable will likely be implemented in Vue 3.5 (as mentioned in the video). Then that should be really easy! Until then, check out Daniel's vue-bind-once github.com/danielroe/vue-bind-once
@@TheAlexLichter Ah, I missed that. Many thanks! Subscribed!
So how would I manage global state with useState do I create a composable for this and manage the state in that composable? do you have a seperate video on this? I'm sadly a glorified React dev learning vue/nuxt. So the concepts don't click yet.
13:21 why is your last few words sometimes so quiet, that it sounds like you stopped the sentence
your videos opened my eyes.....
Really happy it did 🙏🏻🙏🏻
thank you for making this, great examples!
My pleasure! Happy it helped and the examples were clear 🙌
thanks for the great content Mr Alexander, please if you can make video explaining JS execution/useFetch on server/client like common issues or tips because that confusing sometimes especially in my case where i want to make ecommerce and for example should i fetch the product (singular) on the server for better SEO while the profile page can be ssr false. Thanks Again
Fetch all SEO-related data on the server 👍🏻
Use useFetch/useAsyncData + await it ☺️
@@TheAlexLichter thank you, that make sense 👍
One question, i need the page not to render in the source of my ssr page the "NUXT_DATA" script, or if it has to be in the page which is fine, to not include all of my state, is there anything for that? It does not matter if its with pinia or useState, If its a large application it could include a lot of needless things.
Talked about that a bit in ruclips.net/video/laRJNkG_wls/видео.html
You can reduce the payload by passing less (unneeded) data only 👀
Excellent video! I have a question, why do you think it is wrong to use a global state in a composable even if you are not using SSR. Regards!
Good question! I wouldn't say that it is bad practice overall, but when using nuxt and (one day) switching to SSR, you might run into the issue from above without noticing.
Instead I'd go with a more explicit way, e.g. a "globalState" file that exports these `ref`s/`reactive`.
Sometimes you don't know what component is mutating the global state in composable when composable is used in many place, so debuging can become very challenging. But with a very carefull use, it can be very handy for some case.
First of all, excellent videos! I have a problem that I've been stuck on for a while, could you help me? I have a composable called useQuiz, to handle a quiz, its questions, and the options for each question. I would like to manage the state of this quiz with useState in my composable, but I don't know the correct way to store the result of useFetch or useAsyncData in the quiz variable of my composable to manage the state across all child components. Maybe my implementation is not correct, should the result be placed in the onResponse? Or maybe inside the useAsyncData handler?
useFetch already uses useState (more or less) under the hood. If you want to further alter the data, you might have to save it in a new useState indeed.
You could watch the result of useFetch.
Happy to give better advice with a stackblitz or similar
Awesome video. Been using useState so much in my application; it actually helped me understand WHEN to use Pinia as a state management tool. On a sidenote, may I ask if you would be willing to cover how the wrapper component works in Nuxt? I sometimes get mismatches warnings in my console and I resort using to this component but I never fully understood why and I couldn't find a good answer in the community?
Client-Only "hides" the problem only. I talked about hydration at Vue.js Amsterdam, the talks will be released soon & will link it here. Slides can be found already at github.com/manniL/talk-hydration-vuejs-amsterdam-2024
Video is up now! ruclips.net/video/TYyEjN0UrfA/видео.html
Alexander, I have multiple frontend projects that merge into one using a Nuxt layer. I need a unified state management solution for these projects. For example, one UI manages robot jobs, while another displays job reports. What would you advise for more generic store mechanism? How can I integrate useFetch with state management, considering useFetch is typically used only starting points of component or composable? I feel like if I use state management, I will have to give up useFetch.
Just use an actual database at that point. Or simply Redis. You can use Nuxt's server side API endpoints feature instead of a separate backend application. These endpoints can query your Redis. You'll have to either make the users create accounts or store a randomly created ID in the browser cookies (assuming all of the apps are on the same domain/origin). You can then use that ID (or username) as the key to query the redis db and have shared state between the apps on the server side, but not shared with other users.
Thanks for the explanation!
What should I use instead of useState() if I do not want to create a **global** state? I mean, useState() always needs a key or uses file:line as a key. But what if I need to create an SSR-friendly composable, that should return **new** state (just like a Ref) on each call? Let's say I want useRandom() composable (it's not what I really need, but I think it is a good example to understand the problem).
Without SSR I can just use a Ref. useState() needs a key, but I can't generate a key (that will be the same on the server and on the client) as there is nothing I can use as a source data. file:line key is also not suitable here as useState() will be always called from the same file:line (because it is called inside of my composable). Maybe there is a helper/something to generate a key based on a stacktrace of the current call or an other way to solve this?
Basically, I need a Ref, but SSR-friendly.
You might want to check out Nuxt's latest useId composable or Daniel's vue-bind-once directive! github.com/danielroe/vue-bind-once
Isn’t it actually better not to provide the key & let nuxt generate it automatically so that there is no way you could get a duplicate key in a large project?
The key might make sense if you need to access the state from multiple places in code, however, even then you could just create a wrapper composable around useState without key and call it instead of useState(), couldn’t you?
I'd rather trust my own key (so I definitely won't duplicate it) then on auto-gen 😛
+ It is easier to debug in the devtools (which is the better reason here 🤣)
@@TheAlexLichterYeah, the debugging is a good point!
@@Thr0nSKOne more thing to consider is e.g. when the state depends on a page param, locale or similar!
@@TheAlexLichter True! Good point
Thanks for this informative video!
You are welcome 🙌🏻
There is a problem. I'm using one component outside layout and one inside layout. Both depends on the same state. When I change the value from inside layout, the value of the component outside layout doesn't update in SSR.
// this component doesn't update when the value is changed in layout
// the vaule is changed here
The problem solves when I use inside layout
That is correct as SSR is "top to bottom" and there is no "real" workaround there I'm afraid. You can't update what is already rendered during SSR. See github.com/nuxt/nuxt/issues/19258 for more details
@@TheAlexLichter Thanks for the info
Can you point out when using refs in nuxt 3? pls
You can use refs as you’d do in Vue, EXCEPT “outside” of composables, so as “global state” 😊
But useState triggers my React related PTSD.
keep calm, we don't have that bullshit setState, also it returns a ref
Great info!! what about global state in vue without pinia?
Thank you 🙏
If you need global state in plain Vue without Pinia, then you *can* go for the pattern from the video: a `ref` outside a composable to keep the global state inside. Can also be a `reactive` object holding global state in a different file that is manipulated!
As far as I understand, useState was created for a very small amount of data to provide an instant access through the project. Once I had an interview with a company which used useState as a main state system for depencies reducung. I failed it because of a different vision of the topic😅
Seems like it’s really supposed to be the Pinia replacement inside Nuxt. But I still believe that useState is a completely different tool (even after your explanation).
What do you think useState should be / is used for? ☺️
@@TheAlexLichter I’ve never tested it properly. My argumentation might be pretty weak but I’ll still try to explain.
From my perspective, useState is a global and enhanced version of React’s one. It helps to create small stores that can share needed values between components without extra complexity. I don’t feel that I have a control over data fully as well as I’d do it with Pinia. At the same time, I don’t need to implement useState because I’ve already got Pinia that does the same thing.
I'd argue that you have full control over the data (+ what is actually sent over to the client) 😊
@@TheAlexLichter I think I need to test it. Thank you for the video!
You are welcome! Let me know if you have any more questions 😊
Amazing content
Thanks Cody 🙏
greatt, good channel, good content, good good good
Thank you very much Simon!
I wish the doc was clearer
What is missing in the docs in your opinion?
@@TheAlexLichter I tried to use useState to store the idToken to make a request with useFetch with Authorization Bearer token but struggled with it for hours until I noticed I should use useCookie for this.
It was not clear to me what SSR-friendly means in this case.
@@TheAlexLichter I'm talking about this doc
m/docs/api/composables/use-state
@@TheAlexLichter To be honest there is much missing in the docs. Your videos seem to be a natural extension of the (poor) docs of Nuxt 3. I feel like the docs cover 30% of the Nuxt possibilities. But the team seems to be aware of that if they link to your videos in the docs xD Big F to the Nuxt team, Big L for you. :)
Thank you!
You are welcome!
Honestly I don't really understand your explanation language-wise and systematic. Too chaotic for me.
That’s unfortunate to hear! If you have any specific question, happy to answer it in the comments.
Приветствую, Александр.
Такой вопрос: в каких случаях следует использовать объявление useState вот так: const nameVar = () => useState('title', () => 'что-то');
а в каких вот так: const nameVar = useState('title', () => 'что-то');
И в чём разница?
Я не думаю, что первый вариант правильный.
В видео, где он описывал неправильное использование useFetch эта тема как раз и затрагивается
ruclips.net/video/njsGVmcWviY/видео.html
Она применима ко всем use+Что-либо приколам нукста (в моём понимании)
Применения первого варианта, где
const nameVar = () => useState('title', () => 'что-то');
я даже не видел, на самом деле. Есть какой-нибудь пример?
@@suheugene Пример есть в документации в разделе composables
const nameVar = () => useState('title', () => 'что-то'); allows you to decide when you want to initialize the state and get a fresh "ref" (that is populated with the state) all the time. It avoids issues like we've seen in the plugin, where the values would be "shared".
Good content
Thanks 🙏😊