[Render Props] Every React JS Developer should learn this technique!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello world and happy hacking this is mark from dev mentor live and today i'm going to show you how you can chain multiple components together using a special feature called render props it's going to take about 30 minutes to get through the screencast so let's get started right now to code along with the screencast make sure to download the starter kit repository located in the description if you'd like the completed code the link to that is also in the description let's start by replacing the placeholder text with an unordered list inside of that list we're going to have a javascript expression we're going to be mapping over screencasts the way the map works is you call it on an array and you pass it a function the function is going to return one item for every item that is in your array so we're going to be naming the variable screencast and we're going to be returning one list item for every screencast next we're going to be importing our screencasts from a json file so let's open up our directories and see where that file is and what it looks like inside so the file is in src data and it's called screencast.json and it's an array of javascript objects and each of those objects has a title key and an ext id key the title is obviously the title of the video and the ext id is the youtube id for that video let's add the path to our json file by going down one directory and then forward into data and then screencast.json now that we have our json array imported we can continue with our map so we're going to create a div with a class name of underscore underscore dml underscore list dash item the underscore underscore dml is sort of like a namespace it guarantees that if we import somebody else's code into our app their styles are not going to affect our styles then we're going to do another underscore and we're going to do list dash item which is the actual element name i'm going to prefix all of the styles with underscore underscore dml for devmentor live but you can use any namespace that you would like in your own style sheets we want to be able to click each of these items in the list and be taken to the page on youtube where that video plays so we're going to create a link here with an href to https colon slash youtube.comwatch and notice that it's inside of backticks and inside of a javascript expression this is because we're going to use string interpolation to insert that ext id into the url next we're going to append question mark because we're going to be sending a query parameter and v which stands for video equals now dollar sign and curly braces so that our variable can be inserted into the stream template and the variable is going to be screencast dot ext underscore id inside of that link tag we're going to have an image tag and the src for the image is going to be another javascript expression so that we can do string interpolation so back ticks forward slash thumbs forward slash dollar sign curly braces and inside of there screencast dot ext underscore id then back outside of the curlybraces.png this is a good example of convention over configuration all of our thumbnails are going to be named by the ext id dot png because we already have that data inside of our json then we don't have to come up with an additional value to name all of these images i've included all of these thumbnail images inside of the public thumbs folder for you to use no image tag would be complete without an alt property so we're going to add that and we're going to set it to the screencast dot title we want these images to not be their native size but to be scaled to fit the container div that they are in so we're going to add a width equals 100 to the image underneath the image tag we're going to create a div and inside of there we're going to use another javascript expression and we're going to print off the screencast dot title to preview our work we're going to open up our terminal cdn to the correct folder type yarn start this will start up our webpack development server and once that is up our browser will open and we can see the work that we've done so far let's extract all of this list html into its own dedicated component so we're going to select and cut the list html then in src app we're going to create a list folder inside of there we're going to create an index.jsx file inside of that file we're going to import react from react and we're going to export a default function called list then we can paste our markup after the return now the idea of this list component is that it can be reusable so we can't have anything inside of this list that is going to reference screencasts because we might be giving it some other collection so let's start by giving it a prop called items now let's rename our screencast.map to items.map and our screencast variable for the arrow function to item now we could rename all the references to screencast to item but there's another problem here this markup is very specific to screencasts so if we were to give it some other thing like a collection of contacts then this markup would no longer be valid so we're going to use a technique called renderprops to pass in the markup that we want to use for this list let's start by going back to our app component and we're going to import list from dot forward slash list then the return of our app component we're just going to return our list component and we're going to pass items as a property and give it our screencast collection once we save this file the webpack dev server will reload our browser so when we go back to the browser we can just make sure that we haven't broken anything so far back in our list component we're going to highlight and extract the div that has to do with all the markup for the screencast then we're going to go to src app and create a file called screencast dot jsx we're going to import react from react and export a default function called screencast and we can paste our markup after the return of that function next we're going to add the props for the variables that we need in this file which is ext and title then we're going to delete item dot in front of each of these because we won't need it anymore back in our app component let's add a render prop to our list component and inside of there we're going to pass an arrow function the variable is going to be screencast and we're just going to insert a screencast component and then pass the two props that screencast takes which is ext id and title now let's import screencast from dot forward slash screencast back in our list component now let's add the render prop to list and inside of our li tag we're going to add a javascript expression we're going to call render and we're going to pass item to it item is representing the screencast in this instance but if item was a contact or a video or something else then that's what it would be passing to the render prop after we save and our browser refreshes we can see that the refactor works and we can still see the exact same display as before the main difference is our list component no longer references screencast and yet it still works to display our list of screencasts we still have one more thing to do right now which is if we go back to the browser and we do it inspect element and then we go to the console we can see that we have this warning each child in a list should have a unique key prop so we're going to fix that now to do that we're going to go back to our app component and in the call to our list component we're going to add a prop called id that's going to be a string and we're just going to pass the value that we will use for that key this value is used by react to reconcile the virtual dom so the value has to be unique and we're in luck because our ext id is also unique and so that's what we use now we can add that id prop to our list component and down in the li tag we can add a prop called key and we're going to pass a javascript expression to it and the value is going to be item and we'll use square brackets and pass the key item in this case is a json object and the id contains the key so the square bracket notation will allow us to essentially use a variable as the key name for that javascript object when we save and go back to our browser we can see that the warning has now gone away now let's make a way of filtering our list so we're going to put a function call down on line 7 and call it filter and we're going to wrap our items array then on line 4 we're going to create that function it's going to be called filter and it's going to take a single argument which are the items and then we're going to return items.filter which takes an arrow function we're going to name the variable item and we're going to return item.title we don't want screencast specific data inside of this list which is why we're going to use composition to connect multiple components together so that we're not hard-coding values inside of these components that prevent them from being used with other data so we're going to have to take a different approach here let's back out those edits and try this a different way let's go back to our app component and let's define the function that will actually filter our screencasts so we're going to do that at the top of the app component and we're going to call it function filter screencast we're going to pass a collection of screencasts to it as an argument then we're going to return screencasts.filter which again takes a arrow function we're going to call the variable screencast we're going to be filtering on title so we're going to do screencast dot title and since we want to do a case insensitive search we're going to call dot 2 lower case then we're going to do a dot index of which is going to return the index of the first matching character and we're going to pass query which we haven't defined yet dot to lowercase so we're comparing the lowercase title to the lowercase query which will make it case insensitive then we're going to do a check to see if that value the index is greater than negative 1. the way the index of works is if a match is not found it will return negative 1 as the index if the match is found at the beginning of the string you'll get a zero and if the match is found somewhere in the middle of the string you'll get whatever character index where the match begins next we're going to make query something that we pass into our filter screencast function as an argument now down in our call to the list component where we're passing the items prop we're going to wrap our screencast inside of our filter screencast function and we're going to prepend query as the first argument to that function so where does this variable query come from we're going to once again use renderprops in order to give that query its value so let's cut out the list component and we're going to replace it with a call to a filter component filter is going to have a prop called render render is going to take an arrow function the variable is going to be called query which is where we're going to get that value the return of that render prop is going to be our list component so we can just paste that back in back at the top of our app component file we're now going to import filter from dot forward slash filter and then in src app we're going to create a folder called filter and inside of there we're going to create an index dot jsx file you can see that we're using the same patterns over and over to develop our app which is good because that will reduce the cognitive load when you're looking through your folders and your files trying to figure out what is what it also reduces the number of unique file names that we have to come up with because we're using this convention over configuration of having a folder for the component name index.js being the first file inside which is the entry point which also means that we can just import list or filter and it will automatically find the index.js file inside there we don't have to put it inside of our import so again inside a filter we're going to import react from react and we're going to export a default function called filter we're going to return a div and inside of that div we're going to have an input tag that we can use to input the query that's going to filter our list when you have a html element in react and you give it a value it becomes a controlled input which means that you can't really type inside of the input because it is locked to that value however we can add an onchange handler to it so that when you type something into the input tag it's going to save it to state which will then update the value which will then display the thing that you typed in the text box so our value is going to be called query which will be a piece of state and the on change is going to fire set query which will be the setter for that state we're going to pass e.target e.target.value to our set query call e.target is the text box and the value is the value of the text box next let's add our render to the props of filter and then in order to use state we have to import ustate from react and it's a named import which is why it's going to be in curly braces now we can create some state for our user inputted query we're going to do that with const square brackets the first value is the getter which is query the second value is the setter which we're going to call set query that's going to be equal to the return of use state and use state takes a single argument which is the default state which we're going to make an empty string because an empty string will match any other string when used inside of an index of call so let's save this file and then go back to our browser we can see our text input box is displaying if we type inside of it and we switch over to the components tab of our inspector we will see the value that we're typing that's because that value is being saved in state and the state is being propagated back to the text box in order to see the components tab inside of your inspector for your browser you're going to have to install the react dev tools extension for your browser back in our filter component inside of our input tag let's add a placeholder property that's going to be set to a string and we're just going to put something like type to filter the screencast however this introduces text about screencasts inside of our filter which we don't want so let's cut that string out and replace it with a javascript expression and a call to placeholder and then let's put placeholder in the top in our arguments to filter which is where we're destructuring our props into the individual values render and placeholder back in our app component in the call to our filter component we can now add that prop for placeholder and paste our text there after saving the file we can go back to our browser and now we can see the placeholder inside of our input let's get our items displaying again so we're going to go back to our filter component and down underneath the input tag we'll place a javascript expression we'll make a call to render and we'll pass in our query that's how the query gets over into our app component which then goes through the render props it goes down the chain the composition works and we can now filter our list yet our list doesn't know anything about screencasts and our list doesn't know anything about the filter and the filter doesn't know anything about the list and it doesn't know anything about the screencast this is the beauty and magic of composition since we're focusing on component based design and development in this screencast let's extract out our input and turn it into our own text field so let's cut the input html out and in src app we're going to create a folder called text dash field inside of that we're going to create index.jsx i'm sure you can guess what the next step is we're going to import react from react and then we're going to export a default function called text field and then we're going to place our markup after the return of that function next we'll identify the variables that need to be turned into properties so we have this value equals query query is not really part of our text field so let's change that to value and put it up in the props then our handler makes a call to set query which again is not really related to our text field so let's change that to a call to on change which also gets added to our props finally we need to add placeholder to the props of text field since we're making a generic text field component we're going to want to also add type to the props because it might be a text field it might be an email field it might be a number field it might be a password field and so we need to have a way of passing that down into our component however we're going to make it an optional value which means that we're going to set a default to it so it'll be type equals text now let's go back to our filter component and we're going to insert that text field component inside we're going to add the props value and set it to query and on change which is going to take an arrow function which will give us access to the value which we're going to call val the return of the arrow function is going to be a call to set query where we will pass that value next we'll forward the placeholder prop from filter down into the text field next we'll import text field from dot dot forward slash text field inside of our src app folder there is a styles.css file inside of that file there is a class for our text field so let's use that now to style it back in our text field component we can now add to our input tag class name equals underscore underscore dml underscore text dash field after saving our file we can go back to our browser and we can see that our text box is now nicely styled and we can still do all of our filtering when i'm building react components for myself there are many times that i just skip using prop types because it's my code and i know what it does however if you're going to be building components for reuse it's a good idea to use prop types so what are prop types essentially prop types are a description of the props that a component will take and what prototype or shape that prop should be so render is a function placeholder is a string render is required placeholder is required let me show you what i mean as we add some prop types to filter list and text field we'll start with the filter component and we're going to import prop types from prop dash types next we'll open up our terminal and we'll do a yarn add prop dash types this will import that library into our project next we're going to go to the bottom of our file and we're going to do a filter.prop types notice the lowercase p the capital t equals a new javascript object and we're going to list our props here the first key is placeholder and that's going to be prop types notice a capital p this time dot string dot is required this just means that this property is a string and it is required and if it isn't required or it isn't a string then show a warning in the browser console next we're going to do the render property and that's going to be proptypes.func dot is required again this is because it's a function and it is a required property now let's do our text field component so at the top we're going to import prop types from prop dash types and again at the bottom text field dot prop types equals a javascript object text field also has a placeholder and that's going to be prop types dot string dot is required now you could make an argument that placeholder in both of these components could be optional but i think that it contributes to the user experience even if it's not required for the component functionality so i'm going to leave these as required the next prop that we have is type which is the type of text field and this is going to be prop types dot one of and then we're gonna say it can be text password email or number because these are the built-in types that we want to support we're going to make that one require two although technically we could leave it optional because at the top of this component we did set a default value to type so if the person using this component forgets to give it a type it will default to text next is the value so that's prop types dot string dot is required and finally we have our on change handler which is prop types dot func dot is required finally let's do our list component and of course at the top of the file we're going to have to import prop types from prop dash types and at the bottom of the file we're going to have list.prop types equals a new javascript object we're going to start with the render prop and that's going to be proptypes.func dot is required then we're going to have the id prop and that's going to be prop types dot string dot is required and then the items prop and that will be prop types dot array dot is required and finally let's reload our browser and make sure that we haven't broken anything and the filtering and everything else still works and that's all there is to it if you enjoyed today's screencast please hit that like button and consider subscribing to the channel if you have any ideas on topics you'd like to see me cover in the near future on javascript or react.js then leave it down in the comment section below and i'll add it to my list that's all for this week and i'll see you next week happy hacking you
Info
Channel: devmentorlive
Views: 3,032
Rating: undefined out of 5
Keywords: online coding for beginners, software, technology, software development, learn to code, become a programmer, write codes, web development, javascript, build web pages, render props, reactjs composition, react composition, component composition, compose multiple components together
Id: OMzcmpLZHAw
Channel Id: undefined
Length: 25min 5sec (1505 seconds)
Published: Mon Sep 14 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.