ReactJS DataTables - Render Props, Sorting (Part 1)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
and while yarn is starting up i'm just going to do a walkthrough on what we did yesterday so we have a create react app project generated right here i don't need that light in my face and our folder structure works like this we've got our source folder inside of there we've got an app folder we've got a data folder inside of our app folder we have a data table folder that contains our reusable data table component of course there's an index.jsx file and there's a styles.css file which we will probably do more with today because i would like um i would like the data table to look nice and styled then we have a index.jsx for the entry point to the app and there's nothing special about that at all so let's look at our our uh data table the data table is essentially a component it's a it's a functional component we can pass in a number of items we can pass in a render head uh let's see what are we doing here i'm at work and can't watch please upload the channel and i'll watch later yes we'll be uploading yeah it's way better okay good are you gonna use react of course i'm gonna use react so render head is a render prop and i'll show you where we're using it here's my app component we have some state the state has a place for the photos which we're actually going to change to people let's do this let's go like this and let's say change that to people.json and if we open up the people.json file we can see that we have id first name last name email gender ip address i'm not really sure why i p address is useful but that's the data that we have and so the idea here is like we should be able to reuse our data table without actually rewriting any of the code because it is a reusable component at this point so let's change this let's just call this uh let's just call it data and we're going to be now passing in data data and okay so here's our data table this is where we're using the data table so we'll change that to data our headers are part of a render prop so when i say render prop what it means is basically we're just passing a function to our data table that function is going to be called inside of our data table to render out the things that we want rendered um get that going again okay so we've got id we've got first name last name and let me just move this osb down so that if for some reason i'm not showing the right screen i'll be able to to know ahead of time last time i was doing stuff and you couldn't see it for a little while so we got first name last name email gender i p address so email gender hopefully nobody freaks out because i didn't generate this data so if it doesn't have your favorite gender don't blame me okay so that is the render prop for rendering the head and if we switch over to our browser we can see that we now have a a header that has those values something else i notice is that the data table is not expanding all across the screen the way i want it so let's go into our data table here and let's look at the html and in order for a html table to expand across the screen you actually have to give it a width of 100 and it still is not expanding across the screen so let's find out why ah because looks like it's got a 100 pixel max instead of a 1000 pixel max there we go and let's change that to max width and in fact i don't know why we even need that in there let's just uh expand it this way that's really quite odd what is preventing this from expanding across the screen oh well i'll look at that later so this is the render head function that we pass in right so we're passing in a render head this is a function that's going to render out our header a render row which is what we will use as we're iterating over the items in our table each item we're going to give back a row and then we're going to pass that row to our render prop so let's update that we're going to have row.first underscore name last underscore name i'm not going to have that thumbnail anymore and we also have uh email what else do we have gender and ip address one more and i know you guys are looking at the browser you're not looking at the code but you can see this stuff pop up on the screen okay good good good let me switch this back to the code all right so now we've done the render row as well now something i've noticed here is we have i know what it is we have a t tr inside of a tr there we go now it's expanding across the page exactly like it's supposed to okay so let's style this table up a little bit um the first thing i notice that i don't like is that the table headers are not lined up with the text because they default to be in styled in the middle instead of being left aligned so the other thing is i always use a namespace in the front of my styles for a component so underscore underscore dml just says devmentor live and i can pretty much guarantee that if i import anybody else's code in my project their css is not going to clash with mine and then i just say look this is also a table and then i can use that as the base to style stuff right so our tr's we want a border collapse on these because tr's act a little bit differently uh than most elements they if they don't if you don't have a border collapse on it you can't really style the color and you can't really style the uh the size of the tr's you can style the individual tds but not the whole dr and we want the table headers i had an asthma attack today so sorry if my breathing bothers you i'm kind of darth vader today we're going to have a th and the th is going to be text align makes the line last text align left and now in the browser we can see that our headers are indeed aligned to the left so that's good the next thing that i don't like about my table here um i actually saved a table well a screenshot of a table which is what you guys saw in the thumbnail i don't know if you saw the thumbnail let's see if i can actually get this to show let's see if i can do an active window window capture i think and it would be there we go all right so let's make our data table look sort of like this although i think to make it look even nicer we'll do the the alt alternating colors on the rows so that you can tell the rows apart a little bit better so anyway that's sort of where we want to go for this and in order to do that back in our styles let me actually just check on the chat let's see what's going on okay so people are just saying hello hello thank you all for joining and let's get back to this all right so if we want to make it look sort of like that the other thing that i noticed is that the the th's and the tds need to have better padding so i'm going to do that like this and i'm just gonna say that the uh padding i can actually get the padding directly out of this with my selector tool looks like it's about 16. um we'll just call it one rem which is browsers default the pixels for the font size to be 16 pixels so one rem is one relative em which means that if you set a route which i don't think we actually did no we did not so i'm a big fan of having one style sheet for each of my components right and since the app component is a component it's sort of like the global component i use that usually for my global styles so i can just do font size here and say that that's going to be 16 pixels and then inside of my index.js x here i can just say import dot forward slash styles dot css and i show you the browser we can now see that we have one rem padding around it but you can see that we've also got padding on the left and we don't want that i'll take you back to the code and let's update that so we want one ram on the top and bottom but on the left and right we don't want anything so now it looks like that and honestly it's a little bit too much so i take that down to uh 0.5 rem and there's a like a kind of like a gray border around everything in that data table that i showed you guys as the example so let's do that too let's just say border one pixel solid and usually what i do is i just start stuff off with a a simple color for typing and then that would be td and then what i do is uh i use a color picker but my color picker doesn't seem to be working right now okay well i'll do it this way so apparently that color is gainsborough so now you can see that there's this uh this slight gray border to everything and at that point i'm starting to think yeah we'll put padding around everything so there is a padding to the left and right now you can see the uh the gap in the padding this is because in html tables have cell spacing and cell padding and these are not actually style sheet properties these are intrinsic html properties so we'll just say cell spacing is going to be equal to zero and so padding is also going to be equal to zero and i've got them inside of the curly braces spacing i got them inside of curly braces because they are integer values and integers and booleans and objects have to be inside of curly braces so if we go back to the browser now we can see that our our table's starting to get a little bit more styled looks a little bit better also you'll notice that um our infinite scrolling is still working right as i scroll down more and more stuff gets loaded as i scroll down so that's good that's that's the code we worked on yesterday um so to get this to look more like this it's looking a little bit better i really don't like whatever font is defaulting here so let's pick out a font we could use roboto open sands lato monserrata's nice it's also my wife's name source sans pro i think i like this one so we're gonna pick extra light and regular and let's pick semi-bold too so then if you click over here on this embed let me get my face out of the way there we go if you click embed over here it will give you a link that you can put inside of your html so we're going to do that next so if we come back here we open up our project browser we can go to the index.html we really don't need a lot of this stuff let's get rid of the icon let's get rid of the theme we don't need the meta description because we're not trying to get this thing to place well with google search and also we don't need any of the comments and we don't need any of the stuff that is there for the mobile device and instead let's just say infinite scrollable searchable data table how about let's add in another one re usable data table and then let's just copy and paste our style definition in there for the style sheet for the uh images not images for the text then we're just going to go back into our main style sheet which is the one that's for the whole app which is why you see root here and we're just going to put in font family source pro now when we go back to the browser the font looks a little bit better because it's a it's a cleaner font to make it look like this image we're going to need to make the header the bold version and i think we'll make the the rows the light version so what we'll do is we'll go to the style sheet for our data table and we're just going to copy out this and we're going to say that the font weight in this case is just going to be light copy and paste that again this time we're going to go to the th which is the table headers we're just going to say that that's going to be actually i don't think i downloaded the bold i think i downloaded the medium we got light regular and medium so let's go back to the browser i'm not sure if that actually made a difference let's take a look nope it doesn't like medium probably because it has to be in quotes nope doesn't like that either i think 500 is medium and 200 is light that's pretty light let's do 400 and 700 maybe yeah i don't like the way that looks either it's good enough for now okay so the next thing is is you notice that um the lines are super thick and the reason that the lines are super thick is because if we put a border on everything which is what we've done here basically there's a top border and a bottom border and they're right next to each other so what we're going to do is we'll say that the border top and the border left and then you can see that we get a much lighter border because it's not doubling up but then if you'll notice that on the right hand side of our table we don't really have a border anymore and if we put on a border right then we're going to have really thick vertical borders so the way to fix this is to copy the selectors and we're going to say that the last last child is not actually accurate i think it's called last child maybe let's find out and i'll probably have to check to see if we can use that i don't know how ie is with it ie sucks on just about everything yay it works so you can see now we have a border on the right hand side and technically we don't really have to worry about the bottom one because we never really see the bottom because of the infinite scrolling but i guess eventually we're going to get to the bottom and then we don't we don't see a bottom border so let's do the same thing here to get that we want to do we'd want to do i guess the the last tr so we copy that selector again and we're going to do uh tr last child and then we'll take off the last child part here and we're just going to say border bottom and this only seems to be oh i gotta delete that there we go so now we have a border on the bottom but we still have these nice thin borders now let's look back at the thing that we're trying to to replicate yeah it looks a lot closer to that right take a look at the chat window nobody's chatting you guys are so quiet i must have you held in rap oh wait chat just showed up okay let me go through this dev trick says hi mark hey dev tricks how you doing um are you going to use react okay so we've already seen that debug media is this live yes this is live i hope it's live looks like we've been live for about 31 minutes so far and it's all been css to this point but to be honest i am a developer that loves css i like design all right so the next thing that i see here and the the thing that we're trying to replicate um is the idea of these these sortable columns right so we have like this up and down icon and the one that we're sorting by is highlighted and it shows the direction that it is and i don't actually know where they got that icon so let's see if we can find it on hero icons and let's do a search for uh sort well i actually kind of like those better anyway so we are going to copy these as svg all right so the way that i typically do icons and with hero icons hero icons give you an svg it's not an image right um so inside of app i am going to create you know what it's not really part of the app in src i am going to create a ui folder which i'm also going to drag the data table to the idea for the ui folder is these are the lego blocks that i use to build up the features of my site so my shared components typically live in ui and then the app is where all my app logic is let me just see if that got updated yes that got updated so now we've got src we got app then we've got data which is where our json data is being stored and then we got this ui folder and our data table is now inside of the ui let's create another folder here and let's just call it icons now we're going to need a base this should be a folder let me delete that we're gonna need a base icon component i'll show you why here in a second index.jsx component oh no no no no no come on auto complete correctly for me thank you so we're going to call this icon and on my clipboard i already have the svg for this now what i want you to pay attention to is there is this svg declaration html element and then there's the path the path is the part that actually uh changes per icon right so let's just put children here and let's put children here so we're going to pass in a prop call children we're going to render that out here this is in our base icon now let's create another folder inside of icons this one is going to be called sort we got two we got ascending and descending so i'm going to create another folder for ascending replace that with the correct abbreviation asc and i'm going to create one for the descending and you know what let's just do the whole thing why not ascending descending all right so javascript doesn't have inheritance instead used a feature called decoration which is what we're going to do here so we're going to create an index.jsx file inside of our ascending component we're going to call that the ascending icon and we're just going to return that path right but we're going to import our icon base from dot dot forward slash dot dot forward slash base and then we're going to wrap this all right now the reason that we do this is because this part of the icon the base part this doesn't really change but we might want to change like the different color we might want to change these classes w6 h6 which has to do with the height and the width or the size of the view box and if we did that we'd probably want to like have all of our icons look the same right so that's why i'm passing in children children is essentially the path the reason it's called children is any time that you have an open tag and a close tag and you've got some in the middle that the thing in the middle the things in the middle those are children um so now we have an ascending icon let's copy the descending icon and let's just do a new file index.jsx we're going to do the exact same thing here we're going to change this to descending and let's copy that and we're going to paste that here and we're going to delete the svg part because that's already part of the icon all right so now we've got icons for ascending icons for descending and we've got a folder structure set up so that we can do uh things like our own components basically our own lego building blocks so let's put that into use if we come to our data table we have this render head now the nice thing about this is we might not want all the columns to be sortable and depending on the data source that we're giving our data table we might have different requirements for sort so we're not actually going to put our icons directly in our data table we are going to put our icons where they're being used so here's our data table and here's our headers so let's say like we don't care about sorting on the id but we do want to sort on the last name so we can do an import ascending icon let's just call that um sort up icon from dot dot forward slash ui slash icons slash why didn't that auto complete icon sort slash sending so you might want to wonder like why is it called sort up icon here but it's called the ascending icon here the fact that we have exported this as a default function means that the name of the thing actually doesn't matter a lot for our import we can name it anything we want so i'm going to call it sort up and sort down now we could just put it right here we could just be like okay well i'm going to put up put my sort up icon here come on okay for some reason emmett doesn't want to auto complete and i could have my sort down icon here if i go back to my browser you can see that we now have our sort up and looks like we have two short ups ah because i haven't changed okay so now we got sort up and sort down but they're monstrous right this is why we created an icon component that is like the base component because we can put the sizing there and we can make it a default let me switch back to my code and let's go back to our base and our icon so the idea here is we should be setting a size and we're going to default that size to whatever we want to default to i'm going to say that we're going to default to 16 pixels so then here inside of our svg we can say well first off this class is not going to help us because we're not including their style sheets right so let's just put a style tag in and it's going to be a javascript expression and inside of the javascript expression it's going to be a javascript object that's why we have the two curly braces and here we're just going to say that the height is going to be a string interpolation actually it defaults to pixels so we'll just say 16. and sorry not 16. we'll call that size and we'll also do the width and that's also going to be the size that way the resolution doesn't change and now as you can see we have these uh small icons instead of giant icons the next thing is um we want the icons to not be like right next to the text we want that th to expand to the whole width of the header and we want it to well i'll probably use a flexbox so we could just do this for all of these but at that point like it's just going to get messy because we're going to have the same thing over and over also we're going to be putting a flex box on this th so we're going to do something like class name equals flex dash container maybe so let's go into our styles.css and let's define what a flex container is and that's pretty simple that's just display flex and we could say things like you know flex direction row but that's the default and we could say flex wrap no wrap but technically that's the default too and then we can say let's go back to here so now that this is a flex container if we put the id inside of a span and then we put these two icons in a span those are now well technically we could do a div too because it's a flexbox so now our divs instead of going down the screen are going to go across the screen so let's do that and let's say it's a full width so we'll create another stylesheet class for that full dash width and all that means is that anything with a full width is just going to have a width of 100 and that's actually not going to work because uh with on these flex boxes it's not going to matter what we want is one of these to have a let's call it flex full let's say class name equals flex dash full i don't see an error there what's there oh it's missing a close there we go okay so let's go back to our style sheet and let's call that flex full and all we got to do here is say flex 1 which is a shortcut for flex grow so if we come back to our browser now we can see that the icon for the sort up and the sort down are both to the right now because of our styles and i'll take a minute to look through the comments so let's see what's going on here better background color of rose each odd gray yeah we're going to do the uh the the rows is this using the react table package nope we be building our own code because we're developers and you know like if you can write your own code write your own code i got news for you guys companies do not hire you because you know how to do npm install companies hire you because you're a coder and you know how to write code now am i saying that you should never include anybody else's code in your project nah i'm not saying that what i'm saying is if you can build it yourself build it yourself then when you find a bug in it you can fix it yourself immediately you don't have to wait for somebody to accept your pull request you don't have to fork their project do some hackity hack thing to make it work for you upload a pull request to somebody else's project and then hope that they finally put it in and then you can switch from your fork back to their project and hopefully they keep their project up to date right like the thing about writing your own code is you can make it do what you want it to do so the problem with react table or react drop-down or any of these libraries is eventually your client is going to come to you and they're going to say it would be really nice if this drop down or this table or whatever if it did x and you're gonna say okay let me go look at the documentation and i'm gonna see if i can make it do x x being whatever feature they're asking for um i guess i'll get a little bit vain here and switch to my camera for this since i'm waving my hands around um so they say i want this drop down to do x and so you go to the documentation and you're looking and you're looking and you're looking and you're trying to figure out a nice way to make a do x um the problem is they didn't build that thing for you they built it for themselves and then you know everybody else said pull requests pull requests pull requests can you make it do this can you make it do this can you make it do this before you know it that that npm package that you're using has blown up in size and in order for them to make it work for everybody they have to make the code more and more generic and it gets harder and harder to read the code and it gets harder to make the code do what you want it to do so you look through the documentation and you realize this doesn't actually do what i wanted to do and i don't really see an easy way of doing it so you go back to your client and you say sorry can't do it and that's not the thing that you want to say to your client so if you start from the beginning by building your own components and keeping your own library of your own components you get two benefits one is you can always make it do what you want it to do two is you start to have your own style there's a feel for projects that come from your code if you compare two great guitar players or two great pianists or two great drummers or anything they sound different they could play the exact same guitar and sound totally different and that's because they have a different brain they have a different central nervous system and they have different fingers and the the style that comes from the way that david gilmour's fingers land on the strings is very different from i don't know the way john mayer plays guitar right it just sounds totally different and the reason for that is because it has his own personality in it and if you start building your own components you will have your own personality and your components your components if you do your own styles too if you do your own design your components will have a certain look companies think that they want their website to look like everybody else's until they hire a designer and they realize that actually no we don't want our website to look like everybody else's we want our website to look like our company we want our mobile app to look like our company we want to have this feel that is congruent in our company and if you're just ad hoc grabbing this package in this package in this package and shoving it all into the app two things happen one you blow the size of the app up immensely because you're putting thousands of lines of code into the app you're not even using it's just there because it's part of the package and it's because all these other developers have said we want to have this and this and this and this and this and this and this inside of it the other thing that happens is the site doesn't look the same because your text boxes are from material and your drop down is from react drop down and your data table is from like some virtualized data table software whereas if you write your own again you can make the whole site look like it's the same thing which is really nice anyway so back to the code so just to reach out for the people who are just joining us this is the data table we're building we're currently about to start doing the sorting we needed to have icons to do sorting so we have these two sort icons currently they're just sitting inside of this render prop for the header this render prop for the header just allows us to have custom data have custom headers even though the data table is reusable the way that is formatted is custom to the data set now i've decided i don't want to sort on the id i don't think it's useful so we're going to apply this to move those over to the first name um but if you're looking now you'll notice uh some strange right like for one the the the basically we have a wrap when we shouldn't have a wrap which is making uh the id field get all weird because we've got this this div inside of it if we put it back we still have a weird wrap again because we've got this div inside of it so i don't want it to be sorting on the id but i also don't want to see that weird thing right there so basically what it comes down to is we need to make sure that our flex boxes don't wrap and that's because i didn't copy the flex container over what the hell just happened there okay so maybe we can't have the flex container in the div because of the the way that uh the the border collapse is done maybe we have to put it inside of a div yes okay so now you can see that like this tr it's starting to balloon in size and also there's a principle called dry don't repeat yourself try to keep your code to not have as like if you can copy and paste over and over in your code you're doing something wrong so what this tells me is at this point that we need to have a custom component for the th that builds this this format into it because they're all going to look the same so we have to do is we have to identify what's different well some of them are going to have sorting and some of them are not because like the id here doesn't have sorting the name has sorting and also the label of the header is different this is first name this is id so i'm just going to create for now i'm just going to put it directly inside of app i'm just going to create a component called tr and index.jsx create our component by the way the auto completion that you see here this is emmet but it's also because i have special vs code snippets and those snippets are in github.com devmentor live and just look for the vs code settings actually no github.com mark tayyis t-e-l-l-e-z and inside there you'll see my vs code settings okay so this is going to be called tr and again i was talking about we have to figure out what is different well um is it sortable and we're going to set that to false so if you add a sort of a property it becomes true if you don't do anything it just defaults to false also we need to know what the label is going to be so what this allows me to do is i can just come over to here and i can just copy that paste it here and then i can do conditional rendering here and say if it's sortable then we're going to do that otherwise we're just going to do a null so that's just a ternary and now to use this i can come back to here we're just going to import it so import tr from dot forward slash tr this is probably going to end up somewhere else but for now that's fine and i'm going to need to bring over our sort icons which would now be one down from here like so then to use it i can just start replacing this stuff so tr this one's not sortable so i'm not going to even give it a sortable value and instead i'm just going to say this has an id for the label it's a self-closing tag this one is first name and this one is sortable so you notice that i'm not actually giving it a uh i'm not saying sortable equals true this is the default paradigm in react if you have a boolean for your component as a prop you default it to false in the props right here then if you want to make it true all you got to do is just put the property on there you don't have to give it a value react best practices right here on devmentor live so we also want the last name and we also want the email and i don't think we care about sorting on gender and i don't think we care about sorting on the ip address so i'm going to take it off of those like so all right so let me switch over to the browser and now you can see that i didn't put the label into the component let me fix that now there now it's fixed so they're not all the first name okay so the next thing that we want to do here is we they're they're they're both black so it's like they're both activated and a you can't be sorted both directions at the same time and b you can't be sorted on all of the columns at the same time you have to pick a column and you sort on that column so let's make it so that if it's active it's going to have one color and if it's inactive it's going to have another color come back to our code let me just check the chat nobody's chatting okay fine so here's our short icon now what we want to do is we want to have a a way of designating if it's active right so let's just put active then we're going to go down into our icon base and we're going to add active equals false and then we're just going to pass active on through so fill current color so we can change this to do a uh conditional rendering right so we could say if it's active then let's say it's gray let's say it's black let's say it's blue we'll pick a better color of blue later and if it's not active we'll just say that it's gray so right now you can see that they're all gray right and i thought we made one of them active we did so why are they great well let me go to hero icons and look at the documentation for bill where is the documentation so you got fill and you've got stroke and you can use this with tailwind css so when you're looking at these values those are tailwind css classes but i'm not using that i'm pretty sure that i can uh give a value for phil bill none well there's more than one way to skin a cat we can also do let's see sort of icon oh you know why because sort up icon active we haven't actually put that in our ascending and descending so we need to pass active and then we need to send active to our icon same thing here active send active to our icon and now it's active it's black otherwise it's gray and our tr says that the sort of okay so right now all of these are essentially hard coded as active which is why you now see that the the black one for the sword up and the gray one for the sort down and it's it's for all of these which is not actually correct yet okay so we have sortable as false let's also pass in sorted and we're going to default that to false so if it's sorted it can't just be false because we have to know if it's sorted and if it's sorted up or if it's sorted down so let's say that this defaults to let's not give it a default all right so we can do here is we can say active is equal and we could say sorted um is equal to ascending and here we can say sorted is ascend is uh descending now they're both gray so let's pretend that this one is sortable and it's sorted as ascending so now you can see that we have a single black icon and the rest are gray so that's how we're going to deal with the icons and the sorting everybody following me so far looks like we dropped down to only nine viewers on this stream excuse me well you can't see when i'm coding because i was showing you the page so that you could see the page update what you were supposed to be looking at is the icons the icons show the single black one and the gray one right i'll show you the code here while i'm waiting for some comments to come in so now we have sortable and if we come back to here you can see that sortable just does the conditional rendering on whether or not we're going to see icons at all then we have sorted and sorted will take either ascending or descending or nothing so if we come back to here we can see that if it's sortable we get the icons and then if the sorted is ascending then the sort up icon is going to be active and if the sorted is descending then the sort down icon its active will be set to true if we go to those we can see that active just gets passed from the icon down into the base icon and if we look at the base icon we can see that active defaults to false if it's active it's black otherwise it's gray and we could as far as i know change these to any color so now you can see that the value is blue so for the nine people that are still on the uh um live stream what do you think so far any comments any questions there's like a 25 second lag or something so i'm just going to give it a moment be be very very quiet omar says dope actually working on a data grid for myself for a crm awesome melvin phillips says nope i understand excellent day my friends all right let's get back to it so now we have this tr component that allows us to give it a label the label has all that built-in flexbox stuff we have our label for first name this is a sortable field currently it's being sorted as ascending so now we need to have a place where we know um if something is being sorted right so the place to do that is our state and if we look we have a complex piece of state as a javascript object because we have more than one value and because of the asynchronous nature of state and react components if i have more than one piece of state that are going to change together or reference each other i tend to just collapse them into a single object that way i don't have to worry about race conditions essentially and i do this because to me this is just so much simpler and straightforward than a used reducer pattern for one all the code is right here in front of me i don't have to look at some other file and see what are the actions what are the reducer what's the reducer look like what do i have to dispatch what constants do i have to import all that stuff i just prefer it like this so we need to also have a place to track how is the table currently sorted right so let's just say sorted by which is going to start off as null it's not going to start off with anything sorted it's just going to what how it comes out of the the json file or the remote server or wherever the date the json is coming from that's the default sort if we wanted to change the default sort we could make a function to do that or we could just call you state directly i tend to just call you state directly right so now we have to make a way of doing the sorting so here's what i'm going to do i'm going to pass in another property to our tr component and it's just going to be called sort and sort is going to be a function that's going to return the direction and all we're going to do here is we're going to call set state and we're going to use the version of set state that gives us access to the previous state as an arrow function we're going to be returning a new javascript object we're going to spread out all of those previous values back onto our object and then we're just going to call sort it by first underscore name so how do we actually get that to work well if we go into our our tr component we're going to pass our sort function in and all we got to do is put on some on clicks so on click we're going to do an arrow function and the reason that we put an arrow function inside of our on clicks is if we just called uh sort and we pass you know ascending what's going to happen is is as soon as this thing renders um we're gonna get a error uh that's not the error that we're supposed to get one second the reason for this is sort we're calling sort sort is not a function so it is a function it's right there it's clearly a function we're passing sort in we're calling sort anyway we should be getting a too many renders error but we're not getting that so let me actually do the same thing here for this one and this is going to be descending right so we have a sword icon that has an on click that on click is going to make it go to uh sort ascending and this one's going to be sort descending but if you remember like we this is sort of built in because we have these icons we could put it directly on there in fact let me switch over to the browser and let's go to let's open up our react dev tools all right and let's look at our app so we have our state which has the data and we see sorted by is null now when we click on these nothing actually happens yet and the reason why is let me go back to the code we put an on click handler onto these but it's not really going anywhere because this is not an html element this is a react component click handlers have to be on an html element so we're going to pass the on click down into the icon and we're going to pass the on click to here and the same thing with descending okay so the reason that we did that is because now this svg thing that's actually the thing we're clicking so if we want it to be clickable we have to put it on click on here and we'll just call on click now if we go back to here and i switch over to the browser and i move my fat head up here we can see that now there's a sorted by so we click it we get the sorted by whoa blow up all right so it blew up on the sort up but it didn't blow up on the sort down so the sort down worked right like look if we go here we open up our state currently sorted by us null we click the sort down sorted by first name which is actually not accurate we need to know which direction to sort as well not just the thing but which direction if we go over to here we click on that one then we get this sword it's not a function ah but that makes sense because we're passing a sword in here we're not passing a sword into last name email like there's no sort call here okay also i think what we really need here is something like this let's see so this is the field name we go into here we need to say what the field name is so we're passing in a call to set state ah we need this right so what we're going to do is we're going to say first name is the the thing that we're sorting on and the direction is the direction so if we look now we click this first name descending first name ascending oh you guys don't see that okay so back in the browser if we click on this we get sword name descending and if we click on that we get sort ascending so it tells us that we're sorting by the first name and we know the direction back to chat any new questions yep if you don't put it in an arrow function it'll run as soon as it renders and if you're rendering something that changes the state every time your state changes your component re-renders right so if you render an on click that changes the state without it being an arrow function it will change the state which will cause the component to re-render which would cause the component to change the state which will cause the component to re-render which is why you get the too many redirections or too many renders error all right so we don't have a lot of questions i'm going to go back to the code and we know that we can do that now we got this curious problem if we click on this it blows up and that's because we're not actually passing a sort function to the last name all right so it seems to me like we could just copy and paste this right but if you remember i already told you if you can if you can if you can make the code change by copying and pasting it means that you're not at the right level for your solution so i don't actually want to do that i don't want all that code repeated over and over so i need to come up with a pattern for it so my thought is instead of sending in all of this stuff what if we just sent in what we're going to do with it and what i mean by that is maybe call something like sword action we'll just leave it for sort so we're going to call set state when we sort it seems to me that the rest of that stuff should just be inside of there here's what i mean by that this just says where the thing is going to be saved so we could move all this stuff into here and in fact let's just call that set state so we're passing our state in and let's do the same thing here okay so we have other data though we have the direction is easy right because this is sort up so we know what the direction is the direction for that is ascending the direction for this one is going to be descending but we have this first name uh the first name key it doesn't make a lot of sense for that to be here so here's what i think we're going to call this sort and we're going to pass in a tuple the first one is going to be the field that we're actually going to be updating and the second one is going to be the function that we use so let's go back up to here let's change this back to sort and ah you know what actually i don't like the idea of a tuple i don't like the idea of a tuple because without names we have to work on indexes and if you have to work on indexes you have to memorize what is the index and if you get them mixed up it causes problems so i'm going to turn this new javascript object i'm just going to say look the key is first name the state changer is going to be called set state and now i know if i have the sort function i'm going to be changing the sorting on uh first name to the set state but when i look at this a little bit further it seems like i'm passing too much responsibility into here which i don't like well i guess let's go with that for now so this is going to be called sort dot changer and this is going to be called sort dot key and if you're going to have a variable as a key name you got to put it in square brackets all right so i like how that that comes out the other thing here is what's the difference between that and that and the answer is only the direction so let's do this let's create a function and let's call maybe change sort and direction now goes inside of there we get rid of the arrow function and down here now we could just say on click whoa on click arrow function change short this is ascending do the same thing here and that one's just descending and so i think that's a lot cleaner we have a function that handles the actual uh changing we pass the direction in we set the direction here so let's see if this works we're going to go back to our browser we're still rendering so things seem to be okay currently we have a sorted by of null which is interesting because i still see this this highlighted let's click on the sort down so now we see first name descending and if we click up we see first name ascending okay so let's add that to last name so now i should be able to do last name ascending last name descending okay i'm just going to add that to the other sortables which is really just email and so now we should be able to do sort by email and yes i know that you guys can't see the code currently so let's just switch back over so all i'm doing is i just added our sort each of these these table rows but the part that is actually important to see is here sorted by null we click it now we got email ascending email descending last name ascending first name descending so now we have a way of knowing which thing is sorted and how it's sorted let's fix the active icon because this one is showing that um it's active and it shouldn't be so to do that let's go back to our code and we have this active and we're passing that in by if it's sorted ascending i think we can actually take that out because here's what we're doing we're going to change up the sorted by then we can say sorted by is equal to state dot sorted by let's do that here let's do that here and honestly at that point we really don't need sortable either because we'll know that it's sortable if we pass in a sorted by and a sort let me get rid of sortable and we can just change this to uh if sorted by has a value then it's sortable okay so now we need to know okay well is the sorted by ascending but it's not just that we also have to look at the key name and we get the key name from the sort let's take a look at the browser let's look at our tr and i noticed that our short icons disappeared so the reason for that okay so sorted by is null okay so we can't use sorted by for the for the conditional rendering we'll use sort so if you pass in a sorted function then it's sortable right so now you can see that our sorted icons come back and they're all gray so now sorted by is first name and it has ascending so if we come back to our code we now have the sorted by which is going to have the key name and whether or not it's sorting and we know what the key name is because of the sort dot key and these can be null so we're going to do an and gate on them all right let's see if that works so if we come back over to here i clicked on the sorted ascending and i can see first name ascending and that icon is blue and if i click down we now see first name ascending sorted by so if we click over here to last name now the last name is highlighted as blue and sorted by now shows that last name is descending let's hop over to chat and see what people are saying this is nice i've learned a lot in a few minutes i've been here well thank you omar that is my goal and omar also says that he learned variable as a key role the hard way earlier today cool glad you learned something does anybody else have any questions about what we've done so far or if you want to make any statements about what we've done so far um you could give me a pat on the back that way i don't have to break my own arm doing it and i'm going to drink some coffee so far we've been on this stream for an hour and 30 minutes so we've got about 30 minutes left i think we're going to get the sorting in um i don't know if we're going to get this searching built in today but my plan is actually to do another one of these tomorrow because i'm having so much fun doing live sessions with you guys my coffee's empty i'm going to give you guys a chance to make that uh chat move so that i know that you're alive and i'll come back with a fresh coffee and if there's any questions in the chat i will answer them do me a favor all of you guys know other developers javascript react whatever right while i'm going and getting my coffee shoot an email or a discord or a slack or something to some developers that you know and do just give them the link to this and say hey watching this this live stream join us and we're gonna make a party out of it all right and i'll come back with a coffee be right back okay what do you think about hiding the inactive sorting icon if you hit it well i guess i don't have to reply in chat if you hid the inactive icon how would you click on it to make it active so that's why and eric says hi mark thanks for doing a wonderful job yeah man for sure thank you for uh dropping by eric and milan says let's build tomorrow table for me all right let's actually do the part that does the sorting let's go back to the code okay so we now know that we it's active if the sort key matches and the direction matches and if we want to click on it we can change that direction and sort it okay so to do the actual sorting here's how we're going to do it we need use effect and we don't need our icons here anymore the reason that we need to use effect is that we are going to be watching the sorted by and when the sorted by changes will sort our data so let's do use effect and the dependency that we're going to be watching is the state dot assorted by when the sorted changes we will sort so let's inspect that element let's go to our console let's clear and let's click and we can see that when we change it we get a sort awesome so to do the actual sorting um there's a couple of different ways that we can do this one of the problems with the way that we're doing our data with it being virtualized is we're not really loading all of the data into our data table right it's being loaded through an infinite scroll so as you are sorting you're going to not see all the records but i don't know if that really matters all right so the thing that we want to change is we have this page data here we don't want to change we don't want to re-page everything every time we sort and also the initial json is not sorted well it has a default sort when you load the file or you get the request from the server but it's not going to allow us just to sort that data through page data we could here i'll just do that first so you can see what i mean so if we do set state again we're going to use the version that gives us access to the previous state we're going to return a new javascript object so it's immutable we're going to spread out the old state onto the new state and the only thing that we're changing is the data and the data is going to be the same as the previous data except it's sorted now here's the problem in javascript um whoops previous dot data sort we could call sort sort works fine um if you're sorting by the letters by the characters right so right now nothing is happening because we have to actually pass a method to to sort that method is going to give us an a and a b and because it's a bubble sort essentially it's going to be flipping individual fields the the a is the field that you're on the b is the next field it's going to compare them and flip them if they need to be flipped so if it's a number we can compare that pretty easily right and if it's a word we can also compare that pretty easy actually you know what we should be able to sort alpha numerically without giving it a function let me verify that because i don't see it working oh we haven't said what what field we want to sort on either so let's do that let's switch it so we we actually are saying what field we're going to sort on so we're going to sort a dot sorted by camel cased and we're going to be comparing that to b dot sorted by but that doesn't give us the key if we look at the component we can see that sorted by gives us a key and a value so we have to say what that key is so what we could do is we could say keys not there sorted by dot keys dot first or just access it like this but i actually don't think you can do keys that way you have to do object dot keys passing in the array and do that at the index of zero so that would give us the first key let's do that here as well and we would just be changing the b value but those keys don't actually always exist because it could be null we could do something like that although in my opinion that starts to get really ugly and also the key is going to be the same whether it's this one or that one right so rather than try to do all this inside of an arrow function let's let's give it a javascript body and let's say that the sort key is going to be equal to all we got to do is look at the first one we don't have to look at the the b um a not sorted by um but we also have to know if there is one because it could be null i don't like having nulls i'm going to default this i'm going to say that the we're going to sort it by first name ascending by default by doing that i will basically be removing the the chance that we're going to be running and undefined against an undefined you cannot convert undefined object just so you see what i'm seeing i'm getting this error here to debug that error i think i would just put a debugger here and it's still there so it's happening higher up in the stack so i would move my debugger up okay so now i know let me switch over to my browser so now i know that the error is actually happening here and that's probably because we're calling object.keys on a dot sorted by but a dot sorted by does not have a value initially so let's do maybe something like nope that's not working either also i don't like all of this being here let's just do something like um well i'm not going to extract that yet so the problem is can convert undefined to object because this is undefined let's say that if this doesn't have a value we just return which is going to handle the case when we first start but that didn't fix it either still the same error so i'll put a debugger in it let it hit again and let's see what a dot sorted by is undefined what's a okay so a has a value oh yeah duh that makes sense sorted by is uh on the state it's not on the object okay that makes sense so if i was to switch it to state dot sorted by i get first name okay so that fixes that problem so that gives us our short key so then i can say let me go back to my code here so you can see it i can say a square brackets sort key and i'm going to compare that to b square brackets sort key now we're going to be sorting on whichever value it is right go back to the browser you can see that now it's defaulting to saying that we're sorting on the upper sort on the bottom and i saw it switch to sorting to the the names which we see here it's not switching the other way and that's because currently we're just doing it by the by the the field right so if i switch it to here you can see now it's it's sorting by the last name if i switch it here it's sorting by email and we're not sorting by gender right so the part that does the direction is this so it seems to me like we might have to have a ternary we might have to say state dot sorted by sort key that's going to give us the value if that is ascending then we would do the a before the b and if it's descending we would do the b before the a or you can leave those the same and you could just do change the comparison operator there should be no semicolon there and these probably have to be in friends and i'm getting another error so all right so let's see what that the problem with that is basically i was checking to see the state dot sorted by which gives us that and if i did sort key we get the direction let's go ahead and do an assignment um for direction and we can get it by doing the same code so state dot sorted by passing in the sort key gives us the direction okay then we have to be able to say if the direction is ascending we're going to sort one way if descending if the sword direction is the other way we sort the other way and i don't like doing this but i think i might have to although if if a ternary won't work i don't know why a regular if statement would work you know what i'm not going to because i'm stubborn that way i think i can get this to work what happened to my followers close wow this closed all right go back to the browser no error all right so let me just switch the operator around and now we can see that it is sorting based on the field that we want and whoa we got a problem when we did the virtual s or we did the uh infinite scrolling that's weird can't convert undefined to object well one thing these are not based on the a or the b so i should be able to hoist them up to here then if we don't have a sort key for some reason not sure why we would have that problem but if we don't then we could just return and then we wouldn't hit that error on the scrolling let's find out yep that fixed it so let's do a sort on the name we got bees okay so here's the problem this is what i was saying before about sorting the um let me go back to the browser so you guys can see so here's the problem let's sort by alphabetical for the first name we have a's right everything is fine we go down to the bs we go down to the c's d's f's but now watch what happens when we get to that barrier where we load more values now we're back to being unsorted and this is this is why it's difficult to sort or to search virtualized data sets because you don't have all of the data loaded yet right so a while back i said the problem is is we can't sort this because that's not all the records that's only you know whatever 50 of the records what we actually have to sort is the the full json data set so i'm going to create another one a piece of state here we're going to call it um all data and set all data actually you know what i'm going to put that inside of here let's say that all the data let's call it raw data here's our raw data our raw data is going to be the json now what we also want is when we call this page data we want to call page data on the raw data means that this function that we moved outside of our component has to come inside of the component actually no it doesn't because we're passing in the data so we're using basically dependency injection we're passing in the data so we can leave that outside if we go down to here this is what we're calling the page data and right now we're calling it on the json let's change that to call it on the state dot raw data so now we're paging on the raw data that's stored in state so here's what we can do our sort function we can page on the raw data or we can sort on the raw data because the data is based on the raw data that actually doesn't work because it's already loaded in the paging we're going to page data we're going to page the raw data that's our load more function our sort function is sorting on the raw data but that raw data is already loaded into the paging so i guess the only way to fix that is whenever you change the sorting we're going to have to get rid of the the current data set and do the raw data set let me back this up a little bit so whenever we do this we need to actually instead of growing from our previous data we need to actually get our json and we have to do paging on that so the way page data works is it looks like this and we would start back on there so again the first set of data seems to be paged correctly when we go to another set of data it's incorrect again and that's because the sort has to be called on the json on the full json data set so if we do it like this basically i took out the uh the virtualization essentially we take out the virtualization we can see that we're sorted all the way down to the bottom let's uh you know we could do is we could make these toggle i guess so if you click on it again it would flip the sorting i might do that so right now we're on the z's we do get down to the bottom here though as soon as the uh actually that looks like that works so now we've got we've got the virtualization still in and we've got our uh our sorting so if we come over here to email and i say okay sort by email yeah well all the data's loaded though so let me refresh this let's go to sort by email yeah that's working so now we have virtualization ah you guys can't see that sorry there move my fat head out of the way all right so the way this ended up check this out if we sort on say first name we've got our a's right and as we scroll down to get our new data to load we scroll and we scroll and we scroll we can see that the z's are down at the bottom which is what we would expect so our virtualization is still working and we can do the sorting so we've got the first records are now z's and if we load all the records by doing an infinite scroll until we hit the bottom we've got all the a's at the bottom and if we were to switch to like say email again z's at the top scroll all the way to the bottom we got the a's at the bottom so we have virtualization and sorting built in so tomorrow i don't know what time probably about the same time as today i'm going to do another live stream and we're going to put a search filter at the top and probably what we're going to do is make it so that when you click these they toggle so we don't have to have both versions we only have one version and um we're gonna have a search box above this and as you search you can search these fields and i heard somebody ask something about a checkbox uh search when we first started and i asked for a link and i don't think i ever got a link let's see what's better omar says i meant to say the active one oh yeah yeah okay so we're on the same page yeah i think we can make it so that you only show one sort icon and it'll be gray if that field is not being sorted and it'll be blue if that field is being sorted and it'll be the direction that you're sorting so instead of showing both would just show one uh what's better approach handling the multiple checkbox items for filtering the data i'm still not sure what you mean by multiple checkbox items for filtering the data do you mean like you type a in the search field you type of value and then you say i want to search you click the check box on first name click the check box on last name and it'll search the first and last name is that what you meant uh the nomen ahmed and of course i'm going to commit the code in fact i'll do that right now while i'm waiting for my question to be answered i'm going to commit the code and i'll push it up to github and i will put the link to that in the chat for all you kind people so in mind i currently have a menu to toggle off specific columns by toggling off you mean you don't see the columns at all sorry for the lag but that's just the way streaming works well we're over two hours so i think what i'm going to do is i'll pick up on that question tomorrow when we tackle the search and i hope that everybody that was here today um shows up tomorrow and do me a favor share this link on twitter reddit whatever you want and tell your developer friends and colleagues that tomorrow there's going to be another live stream and to show up the more the merrier i will do more and more of these if i have more and more people watching the streams if i only have seven or eight people watching the stream it's not quite as worth it let's say as if i had 100 people watching the stream so let's make this get big i need your help so help me spread the word and i will keep doing this and i hope you guys enjoyed yourself and i hope you learned something and i hope i showed you some clean coding techniques and i will see you tomorrow have yourself a good night be safe everybody you
Info
Channel: devmentorlive
Views: 7,310
Rating: 5 out of 5
Keywords:
Id: 70wozHFsZFo
Channel Id: undefined
Length: 120min 28sec (7228 seconds)
Published: Sun Oct 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.