Svelte State Management Guide (Sharing Data Between Components)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey friends welcome to swell state management today we're going to learn about tools to manage complexity and learn how to manage state in swelt in ways you can communicate between components you're going to learn about passing props bindings component events stores the context api and when you might use them instead of being a prescription so you can find examples on github or if you want to play around and follow along you can open it on stack blitz which is really awesome it should take a second but yeah let's get into it so let's talk about component props by default the data in your app flows down from parent to child component like a river and you can collocate or lift state up to the parent component is going to pass the props to children as you can see in this image here is our app then we have the parent component that shares the common state between these child components and then you can just pass the props and the data flows top to bottom as you can see in this example i have a simple count value i have increment and decrement methods and now we need to somehow make this work if we look at the count component it just accepts the count the current component accepts the increment method and is the same for the decrement component but yeah if i go here and if i open the props example we can see that right now it's undefined so how do we solve this problem we can simply pass it what it requires so we can say increment we can say count and this is just shorthand for this if the value has the same name as well this works just the same and then we can also pass it the decrement and now we can save this and this should work so if we go here we can increment the value and everything works great this really isn't anything to write home about because it's just a basic example right and i also want to stress that this is a contrived example and you should only split your code into components when it becomes hard to manage because hasty abstractions can shoot you in the foot but yeah this is really an awesome talk by can see dots if you've never seen it which i highly recommend if you're unfamiliar with tyscape that's alright and if types spook you you can just ignore them because they're optional valid javascript is valid typescript so you don't have to think about it and if this is confusing to you you just need to try it out and practice it right and then it's going to make a lot more sense so yeah don't just watch but try what you see and that way you can learn a lot so let's talk about bindings if you had to pass input from one component to another and update it to any changes your code might look like this so you would have to create an update input method that gets the event and now you need to update the input by giving it the event target value and this would work and you might be already familiar with it from other frameworks but i mentioned how data flows down but we can use the bind property directive to let it flow the other way so if you look at this image here is the parent component again it has the common state write which is the input among these two components and then we can communicate both ways between the child and parent using the bind directive and the data flow goes to waste so in swelt you can bind values to properties of dom elements but also to component props meaning your child component can talk to the parent component so if you look at the input component here we bind the value of input here and the output component is nothing special right but currently if we look here and go to bindings it doesn't work so we can simply bind the value by saying bind input and now the bind input that's important this component is going to be bound to the input value and we can avoid all of that boilerplate which is awesome but one thing i want to mention is that with great power comes great responsibility so be careful to not abuse bind because it's going to be hard to keep track of your state and what changed it the more you pass it around so use it sparingly let's talk about component events component events are another way to send data upstream based on the custom event api and you can try this example in your developer tool so if i open developer tools you can just create a custom event message that has a detail hello and now we can add an event listener to the window that's the message and then we can alert the event detail from the custom event so if i press enter we're going to see it which is awesome and this works the same in swelt so if you look at this example insult you can dispatch the custom event from a child component and listen for it in the parent component so here we have the parent component as the listener again the common state and then we can fire an event from the children and then the data flows in two directions but one difference is that the events don't bubble like the regular dome events so it means that it's a bit harder if you have a lot of nested elements because you have to pass them along to the other components so this example i just really have a simple area here and want to track the x and y coordinates of the mouse and here i have a simple component where we import the mouse we track the x and y position we update the position here here's the target element and we want to subtract the element left and element top so we only get to read inside this area so how can we do this so if i look at the example here we can first define the event inside the child so inside mouse.swelt we can import create event dispatcher console and then we can create const dispatch create event dispatcher and that's basically it so now we can dispatch any event we want and the parent is going to listen to it so we can say dispatch update position this can be anything you want and i also want to pass the event so i can get the coordinates and here i just listen to mouse move so i can save this and now if we go to the parent and i have it in this code here is the mouse and now we can say on update position so that's the custom event we're going to listen to and then we're just going to trigger update position and now if i save it and go to the example everything should work so this is really awesome and yeah as i mentioned in here component events are awesome but they don't bubble like regular dom events so you have to forward them but you can do whatever you want like having an on submit on your form component or whatever else you can dream up like for example on register on login or whatever and itself you can also forward dom events so if you have a button component that's on click handle click inside the component you can use button and you can just say on click to forward it but yeah that's pretty much it let's talk about one of my favorite features of svelt with your swell stores stores are just objects you can subscribe to and be notified whenever the store values changes and they're great if you have global state as sometimes you have values that need to be accessed by multiple unrelated components so you can see in this image here is our global state it represents the entire app right so if we define something in a store like count then every component can have access to it regardless where it is right so let's start with the most basic example here and i'm excited to show you how you can make a simple toast notification system right here but if you're unfamiliar with stores here's just a basic example so basically we import a writable from swell store and then we can set account to be a writeable zero and then we can use it on a button on click we can increment it and this magic syntax is as well convenient that subscribes and unsubscribes to the store for you saving you from writing extra code and this is basically it so you would literally store this inside another file and then anywhere you import count it would be updated but yeah that's a really boring example so i want to show you something awesome how simple it is to make a custom toast notification system so inside of here i have a simple entry point where we import toast from toe swelt and the toast is just responsible for looping over the notifications and displaying them it has some animations which looks fancy but it's really nothing special and then we're going to import the toast from notifications which are going to create a store right now and then the idea is when you click on a button it's going to display the toast and the future can customize this in more ways you can specify the type of the notification you can specify the duration or whatever else you might want so let me show you how simple this is to do using a swell store as i have the code in this example so we can do it together we can import a writable from soil store and then we can import it we can export cons notifications then we can create a writable and we can just say default as an array and this is just typescript if this was confusing so we're just saying that the values inside are an array of strings which they are right and then it's simple as creating an export function toast we're just going to receive the message right but this can be more complicated like an object so we're going to add a notification and the way we can do it is we can say notifications so this is a method of the store we can say update and we really can't use the syntax the magic dollar sign because you can only use this inside swell components so that magic or convenience isn't available to us here and this is the methods we would usually have to use if this syntax didn't exist right which is why swell is awesome but yeah now we can do this sensor inside the regular javascript or typescript file we can say update and then we get the state back and then we can just put the message on the top and we can spread the old state and that's pretty much it and now we have to remove this message card code it to two seconds we can set timeout remove toast we can say two seconds so now we can create a remove toast function and then again we can say notifications update we get the state and then we can remove the last one we can say shift and then we just need to always return state actually not inside shift right state and this is pretty much it now we made a custom toast notification system that you can customize and expand on however you want but let's look if we look here we just import the toast so this is responsible for showing the notifications and then we import the toast from notifications so we just have toast here and again here it is toast where we passed a message and here is how it works so let's go here to the example if i go to stores now when i press show notification it should show up here and let's see the moment of truth uh how awesome is this and it should disappear after two seconds imagine if you send error notifications or success messages and etc and you can just stack them like this and they're going to disappear after two seconds how awesome is this let's talk about one of my other favorite features of swelt which is the context api the constex api is useful when you have nested components that share state to avoid passing the same props around that's also known as prop drilling but also sharing logic as you can see in this image we have an app and here we have a parent component which we can set the context in and in the children we can get the context and you can see the context is all around this so you don't have to pass props method and etc and for reactive values use context api plus stores right this is a simple example right and i'm going to show you where this is more useful right now in this example but usually you really don't want to abuse contacts for simple components unless they're nested and you have really this problem that contact souls but in this example my goal is for example i want to use canvas and i just want to draw a circle in the middle and let's say for example that i dreamed up this api of canvas to be more declarative so i want to write something like this as you can see on the left canvas circle which is the equivalent of writing this imperative code so how much nicer would it be to do something like this but there's a problem with this approach we would have to pass the reference to the canvas in every component so example if you have more components box text etc now we would have to pass this props all around so how do we solve this problem easy we can solve this problem using the context api so this is where the context api can help us because instead of passing the reference around we can define the context inside the parent canvas component and the children components like circle which we can access the context so if i go to the canvas component we can see here i have the reference to the canvas by using the bind directive this to the canvas so now we just need to pass this somehow to the children right and we can do this in the parent so here is the component we were seen before but now in the canvas swell component we can just go to the top and we can say import so we need to set the context from salt and this is really a similar api to react if you're familiar with that so we can say set context now we can give it the key can we so we know how to get it you know we can just specify a method so we can get the reference this is going to be a get canvas method which is going to return the canvas reference so it's going to return this and now all of all children are going to have the reference to the canvas so now we can save this and as i show you in this example now we can use it so we can import get context and now we can say const cat canvas we can destructure it easily we can say get context and remember the key previously we had now is get context canvas and now we just need to use it so inside this on mount we can just create const canvas and we can say get canvas and also because typescript is mad we can just say hey this is html canvas element and now inside the child we have a reference and this declarative api is much nicer because we just define all the properties x y radio start angle etc and now we have the reference to the canvas and we can just use it as is and now if i go to example here a circle should be in the middle if i go to the context api and it is and how awesome is this and i also want to mention that if you want reactive values you can pass a store to a contact so it's only available to that component and its descendants so in this example i'm importing set context from swelt i'm importing writable from the soil store and then i'm going to declare a value that's a writable set at zero and the value is now reactive when you pass it to context so you have the key and the value the context api is powerful but don't treat it as a solution for everything and use other methods like props bindings and event until you need it so let's talk about module context and before i confuse you this has nothing to do with the context api but refers to the script context module in your spell component so far we have covered things that you're going to use most of the time but this is more of a bonus so i can just show you a new awareness you ever needed so module contacts is useful when you want to share state between multiple component instances so for example let's say you have one component and then you invoke it you for example have hello world then you're going to get hello world hello world etc for all of this but if you have it inside the module hello world is going to get only output once and this is the module context it's literally just javascript so for example this file is a module when you create for example a component js file your console.log context module and then in swelt your components are basically classes at the end of the day so if you have a component in your console logout component now when you import it inside an app for example it's going to log context module once but for every component instance is going to log the message component so this is how it works in swell because your components get turned into classes at the end of the day i have a goofy example because this isn't something you're going to use frequently and i almost never use it but let's say you run some banana processing plants and each time you add or remove a banana you want the data to be shared among the processing plants because we're inside our module context the value isn't going to be reactive but we can use a store instead so here i just made inside the context module imported the writable and then i have a bananas that i can export and use and really here is nothing special we just have a method for adding bananas so now we can change it reactively right and then how do we use it right so this is where the power is so we can just import the production and then we can import the exported bananas and now no matter how many instances the state is going to be shared so here i have for example production and if i go to example here module context so now if i add for example four bananas and now if i go to another component and continue adding bananas it shouldn't reset but it should just continue right because it has the share state so one two three four and now if i want to remove those bananas we can start from the first component if we want one two three four and we can go to anything else then we can just remove the bananas and really this is a goofy example but there's a more useful example in the swell tutorial where they show you how this is useful if you have a lot of tracks playing on a site and you want to say hey pause all of tracks that you can loop over the tracks and pause them which is a more useful example but yeah i wanted to show you something fun but yeah now you're at least aware of it so if the need arises you're going to know when to use it so here is another bonus one what is the first state manager that ever existed for a page you might not expect it but it's the url of course and you can use it for things like coupon codes or referral links but you could also use it to preserve some state over a link so for example if you had a list of ascending items you can maybe send it to someone else where it's in the descending order you can preserve some state and it's like really interesting i don't see it a lot being used but yeah basically in this example i just have some simple list it can represent anything so it's ordered in ascending order which is really nothing special here's a simple component and then we just change the order but in circuit we can get the query params using the page store so we can say page url search params get order and if there's no order is going to be default ascending but now if we go here to the url and if we say order so descending and now it's going to look for this and the list should be inverted right so it's going to use reverse and let's just see if this works so yeah our state works now it's four three two one and everything works the same let's summarize what we learned so far i want to avoid the famous it depends answer and that means i have to give you an opinion that doesn't represent every use case and it's more general to help you pick a solution so here is the swell state management guide and first we start off with do you have deeply necessary components that depend on some state if the answer is yes is the same state shared among your nested components if the answer is yes use the context api plus stores if you need reactive values or if the answer is no use stores and if the answer for the original question was no then the question is do you need to share state across component instances and if the answer is yes then use module context and if the answer is no use props bindings and component events and as i said here i spent a lot of thought and research writing this post but i can decide what state management method to pick for you and i hope at least you have more confidence to make an informed decision so that's basically it and also don't forget that if you find any mistake or you don't agree with something you can edit the post on github and i'm going to gladly have a discussion with you but yeah that's it so thank you for watching and catch you in the next one
Info
Channel: Joy of Code
Views: 21,272
Rating: undefined out of 5
Keywords: svelte, state, guide, tutorial
Id: 4dDjQiOVrOo
Channel Id: undefined
Length: 19min 41sec (1181 seconds)
Published: Tue Aug 23 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.