in this video you're going to be getting
started with react from creating a
skeleton react app all the way to
building this reusable real world
component which is an auto-complete text
box with suggestions that filter as you
type
so what is react
react is a javascript library created by
facebook for building user interfaces
it allows you to build and combine
reusable ui components much like
creating your own custom html tags
these components are declarative views
which update as the data in your
application updates i.e they react to
changes in your application state hence
the name of the library
enough background let's get started
you need a recent version of node for
this to work so if you haven't got that
installed already go and do that first
when that's done in the terminal i want
you to type npm install
g
create dash
react dash app
this will install an npm package that
creates bare bones react apps for you
with all the webpack configuration and
required modules already set up for you
so you can start coding straight away
after that's done installing you need to
do create
dash react dash app
then a space and the name of whatever
you want to call your new app let's call
it my dash
first dash app
and this will set up your new react app
and install all the necessary
dependencies
that'll take a little while and after
it's done you need to go into the
directory that's just been created so
that's my first
app
and you'll see here it's
installed an npm application for us it's
created our bare bones react app and we
just do an npm start
and this will this will compile the app
and run the dev server
it's also in the moment going to open
here we go it opens a browser window and
runs the app in it for you that's very
convenient
so it's still just loading it's still
probably compiling in the background
and there we go and this is the bare
bones react app and you can see here it
tells you to
go to src app.js
edit the code and save and it will auto
reload
so let's do that now
to start off with we're just going to
fly through building a really simple
component with react just as a taster
after that we'll move on to the
autocomplete textbox which is more
useful but also more complex
open the code in an editor of your
choice
and go to the src folder and then you
want to go to app.js
and this is the main top level app
component that renders what we saw in
the browser if you remember there's this
text here about getting started let's
just edit this and change it to say
hello world
and if we save it
and go back to the browser
the code recompiles it hot reloads
and we get hello world
so now let's create our first react
component and then we'll be able to use
it just like a custom html tag really
we're going to make a component which is
a button and some dynamic text
when you click the button it's going to
toggle hiding the text
so in src i want you to create
a new file
we're going to call it hideable
text.js
we're going to import
react
from react
then we're going to export as default
a new class
and we're going to call that hidable
text and it needs to extend
the react dot component class
we give it a constructor
and the constructor takes an argument
called called props these are just
properties for the component and they
can be passed in like attributes are
passed to an html tag
and we do just need to call super in the
constructor passing through the props
and super just calls the parent class
constructor so it's calling the react
dot component constructor that just
ensures the class is set up properly
next we have a very special function
called render
now whatever gets returned from render
is what gets rendered in the browser for
this component so we're going to return
some jsx it's called which is xml within
javascript
and this jsx is just going to be
a div so it's just like doing html tags
within our javascript really it's going
to be a div
and then we're going to have a button
and we'll call it toggle
and then some just some hard-coded text
for now
now we have this component we can go
ahead and import it into our app
component so we open that file
and we just import it import hidable
text from
hideable
text
now we can use it pretty much like a
custom html tag so if we go within this
div class name app content we just go
hideable text like an html tag
we save it and then we'll have a look
and see how it looks in the browser
and there we go we've got our button
that does nothing at the moment and our
text
react elements can take arguments called
props that are a lot like attributes for
html tags
so to our hideable text we'll add one
called text
and as the value just as a string we
will put
dynamic
text
now we go back to our component
and that text prop will be available in
the component within an object called
this dot props it comes in via the
constructor here and is passed to the
superclass
so we want to output this here
and if you want to output the result of
an expression in jsx
you just wrap the expression in curly
braces that's completely wrong wrap the
expression in curly braces so we're
going to do this dot props dot text and
that will be the dynamic text we just
passed in as the prop
so if we save this and take a look in
the browser the text should have changed
so as we can see we've now got our
dynamic text
and the button does absolutely nothing
let's fix that now
props are one form of data available to
a rat component they are passed in from
outside the component as we saw and are
immutable but we can also store internal
mutable data within a component and this
is called state we will define this
within the constructor so we'll go this
dot state
and state is a special property on a
react component so it has to be called
state
and it's just a plain old javascript
object so we can just define it as an
object literal we will add an is hidden
property
defaulting to false
so obviously if is hidden is true the
text will be hidden otherwise it will be
shown
and we can achieve that by going down
here and doing not this dot state
dot is hidden
and props dot text
this means the text will only show if is
hidden
is true
next we need a way to toggle is hidden
so let's go up here let's create a new
method on the class called toggle
is hidden
it doesn't take any arguments
and this is going to use a special
method which is inherited from the react
dot component class
and this is called set state
for reasons i won't go into now because
it's beyond the scope of the video
this dot state should never be altered
manually after being initially set up in
the constructor
so we call this dot set state and this
takes a function as an argument
and it gives us actually the current
state
as an argument to this function
and then this function has to return the
changes we want to make to the state
object in the form of an object
so we'll return an object
and we want is hidden to be
the result of toggling
the current is hidden so current state
dot is hidden
and again for reasons i won't go into
now because it's too complicated for the
moment you must always you get the
current value of any state object
when you're doing a set state from
current state not from this dot state
you'll have to watch my entire react
course to find out why i think it's a
bit more complicated but this toggle is
hidden function will do exactly what we
want
next comes the task of hooking toggle is
hidden up to this button here
it's actually very simple
it's a lot like in html and javascript
without react how you would have
how you would add rather an event
handler you just put it straight on as
an attribute on click in this case
it's going to be an expression so we
want the curly braces again and then we
just put an arrow function and all this
arrow function is going to do is call
this dot toggle is hidden
let's save that and check this in the
browser
first i have just noticed a big error
in toggle is hidden i set the new value
of his hidden to be exactly the same as
the current value which is obviously
wrong we want to negate it so it's
toggled and now it should work
so in the browser we have the toggle
button we have the dynamic text we click
toggle and the text disappears we toggle
it again and it reappears
so that's working as intended
so what's happening here is when we
initially render the button is hidden is
false
and so the text is hidden then when we
click the button toggle is hidden is
called
set state is called and it sets is
hidden to true each time we update the
state of react component the component
re-renders so the render function is
called again and so when we click for
the first time and his hidden is set to
true
this function is then called again this
time is hidden is true and so the text
isn't shown
now we're going to move on to building a
more useful real world component
i'm going to be teaching you how to
build this autocomplete text box using
react
it's one of those text boxes where you
type and get a list of possible items
you can select which fill in the text
box a bit like the auto suggestion
search boxes on most search engines what
i really like about this is that it has
real world uses it's a very simple
component but by creating it you'll
learn about reusable react components
props component state and using css with
react
you'll first need to set up a new react
app by installing create react app
creating a new app with it and then run
it by going to the directory in the
terminal and doing npm start
alternatively you could just put the
code within the app you previously
created it's up to you open the code in
an editor we're going to create a new
component
first create a new file for your
components and call it
autocompletetext.js and it should be in
the src folder
components are the building blocks of
any react application
they can be configured using something
called props more on that later in the
series and they can hold their own
mutable data called state
they can be used to represent anything
in your ui from small things like a
standalone ui widget such as this
autocomplete text box we're going to
create
right up until something large like an
entire web page
components are reusable so you can use
them many times on one page or even
across different pages they're also
composable you can think of them like
lego bricks you can fit them together to
build other larger components
first we need to import the react module
you need to do this for every component
you create
then we create a class to represent our
component and we're going to call it
autocomplete text
it needs to extend the react dot
component class in order to make it a
component
our text box will need the list of all
possible items that it can auto complete
with
in a future video i'll show you how to
make that configurable but for now we're
just going to hard code a list of names
to do this first create a constructor
react component constructors must take
an argument called props and call the
superclass constructor passing the props
argument to it
this just ensures the component is set
up properly
let's add a member variable called items
so it's this.items and it's going to be
an array
we create a member variable so we can
access it from anywhere in the class
later
so let's add some names now to the array
these will be what can be shown in the
autocomplete drop down they're all the
possible items to auto complete with
now the markup for our component
at the heart of any react component is
the render function
it will examine all of the components
data and based on this will render the
markup for the component
the idea is that when the components
data changes the markup changes so the
user sees something different
so we define our render function
from this we must return the react
elements we want to represent our
components
some magic called jsx lets us write them
directly within javascript as html tags
so we're going to return a rapid div and
inside it a text input this is going to
be our text box
we're also going to put an unordered
list to hold our auto complete
suggestions
we'll worry about showing only items
that match the text entered later
for now let's show all the items in the
list
so we have this as an array so we can
just output an li for each item in the
items array
now this is going to be an expression
and to mix expressions into our markup
using jsx we need to wrap them in curly
braces
anything within curly braces will be
evaluated and the value output within
our markup this can be anything from a
simple string to the results of a
function call or even
other react elements
we want one li per item in the list so
inside those curly braces we're going to
map over the array and output an li for
each item
within the li we have the item itself
this itself is an expression so is also
wrapped in the curly braces
the result of this map is an array of
react elements now if we put an array of
react elements within curly brackets
each element in that array will be
rendered
although we're nowhere near finished yet
i think this is a good time to check how
our new component looks in the browser
so far we have our new component but
haven't used it anywhere
we can use the component just like a
custom html tag
the component itself is just the
definition
we need a new instance of this
definition which will be a react element
let's do that now
so you want to go to app.js this is our
main top level component for the app
and we're just going to delete all this
we don't need that header section at all
and we also want to go into index.css
and just put 50 pixels of margin at the
top of the body just so we've got a bit
of space up there when we put our text
box in
so first we need to import our
components module
and we're going to use the component
just like a custom html tag
so it's just auto complete text as an
html tag
so you should be running the app using
npm start in the folder in the terminal
so that it will hot reload in the
browser when you change the code let's
take a look
as you can see we have our text box
and our list with all the names in it
when the user types in the text box
we're going to need to know about it so
we can filter the list so that only
items that match what the user types are
displayed we're also going to need the
current text which has been entered for
the same reason
so let's get that text now
you can add events to elements in react
much the same way as you can in html so
this text input has an onchange event
available
so we add that and we're going to assign
a function to it since a function is an
expression we wrap it in curly brackets
and all the function is going to do is
take the event that has been generated
and console.log
event.target.value or e.target.value
because is the event target is the
element which is the target of the event
and the value is the value of the html
text input
let's check that in the browser
so we right click and choose inspect to
open the developer console
and choose console from the tab above
then we type in the text field
and as we do you can see the text being
output each time we change the value
in order to only show items in the list
that match the text entered we need to
use the component state
component state is just internal data
belonging to the current instance of the
component
since it belongs to the current instance
you can have multiple versions of the
same components on the same page at the
same time and they each keep their own
individual state
so in this dot items we have all the
possible items
we will store the list of items which
match what is entered in the text box in
the components state
the state is initialized in the
constructor
it is just a plain old javascript object
but it must be called state
and must be on the current instance ie
on this
as this is the property react.component
uses for the state
it's like a property which is special to
react
so we're going to create this dot state
and it's going to equal a new object
literal for the list of suggestions
we'll have a property called
suggestions
when the component is first created we
want the suggestions to be empty so
let's go ahead and make it an empty
array
let's create a function to handle the
user typing in the text box
we'll call it
on text changed and it's very important
that it's an arrow function or this
won't work
if you don't understand why this is you
need to learn about function context in
javascript
the function will take the onchange
event as an argument we'll call it e
and now let's go down to the onchange
attribute in the textbox and we're going
to add that function there we just put
this dot on text change there's no
brackets at the end we're not calling
the function just assigning it
so we need to get the value from the
event
if the string is empty
we're going to want to make sure that
the suggestions are empty as there's
nothing to match on
this case would happen for example if
the user types a single character and
then deletes it
now you might think we empty the
suggestions array by doing something
like this dot state dot suggestions
equals empty array that seems to make
sense doesn't it we just
set the suggestions array on the state
to be empty however this would be the
wrong way to update a value in the state
the reason for this is that what gets
rendered in the render function will
probably depend upon the state now in
this case it doesn't yet but we'll be
making render do this in just a minute
the idea is when you change the state
you change what gets rendered so that
the component displays something
different this is what makes react
components dynamic rather than static
for this reason the component needs to
know that the state has changed so it
can re-render call render again and
display the new version of the component
to the user
react.component gives us a function it's
called setstate that does just this
so it's this dot set state
and now this takes a function which will
return an object with any state changes
in it so any properties we want to
change in the state
go in that object the reason it takes a
function that returns an object instead
of just an object is beyond the scope of
this video i do however talk about this
in my udemy course
so we want to set the suggestions to
empty array so the function just returns
an object with suggestions as an empty
array
you don't need to return the entire
state from this function just the
properties you want to change
the else case is if for the text isn't
empty
for this case we're going to create a
case insensitive regex to test for
matches in the items list that start
with the text the user entered
next we're going to define the list of
matching suggestions and put it in a
const and this is going to be defined as
taking the contents of the items array
sorting it alphabetically
and filtering it for items that match
the regex we just created
we then need to update the state
with the filtered list of suggestions
and actually i've just thought of a
better way
of writing this
so we're going to use let and define
suggestions so it's mutable and we're
going to initialize it as an empty array
and if the length of the string entered
is more than zero we set suggestions
to be the filtered list of items
so we just need the regex in there
and then
the filtered suggestions in there as
well
and then after that we just set
suggestions in the state this does
exactly the same thing it's just more
concise
now we're only going to render the
filtered list of suggestions instead of
the full list
i'm going to create a function to do
this which i'm going to call render
suggestions
so we destructure the suggestions from
the state
and if this list is empty we don't want
to show the ul element at all
um to do this we can just return null
from this function
anything that is null won't render
anything to the browser
so next is if it's not empty
and in this case we want to copy and
paste all the code from down here from
the render function or cut and paste
rather for the ul
so we're going to return that
and within that instead of mapping over
the items array which is
sort of all the items that we have
because we only want to output the
suggestions
we change it to suggestions instead of
items
then in the render function we call
render suggestions
in the place of where we had the markup
for our ul
so now what should happen is when i type
in the text box only items which match
the value entered get shown
but we have an error
v.test is not a function it actually
says there's two errors on the page but
they're both the same
let's just go and fix this now
so i've got things the wrong way around
here i've done
text value dot test instead of regex dot
test
and i need to pass in the text value to
the test function so just the wrong way
around there let me go back
try again
cannot read property map of undefined
again just a small bug it's not
this.suggestions.map it's just
suggestions as we've already structured
third time's a charm we're now getting
everything filtered as i type
what's happening is the suggestions are
being updated in the state as i type
each time they are the component's
render function gets called again
and it only returns the list with the
matching items as this is what's in the
state at the time the function gets
called
so we have our filtered list next we
need to make it so when we click an item
on the list it populates the text box
with it
to do this we need to be in control of
the value of the text input
now there are two types of controls in
react or inputs rather controlled and
uncontrolled
currently this text box is uncontrolled
this means the browser controls the
value the user types and the text
appears in the text box
if we make our text box controlled we
control the value via react
we make it controlled simply by adding a
value prop
and we'll set this now to an empty
string
so look what happens when we're in
control of the text box via react i am
actually now typing the text box and
nothing will appear
we will have to set the value ourselves
from within the component
we will set the value of the text box
using the component state to do this
we're going to add a text property to
the state and the value should just be
an empty string
then we want to go down to our render
function
and we want to extract this text value
from the state
and then in our text box
we're going to make that
value prop
the text from the state
so that's what goes in the text box
now we go to the on text change function
and when the text box value changes we
want to set that value in the state as
text
now when we type in the text box the
value updates
to select the item we need a function to
say a suggestion has been selected
so we're going to go ahead and add a
function suggestion selected
it's going to take the value of the
suggestion which will be one of the
items from the suggestion list as an
argument
we're then going to update the state so
the value the text box uses is the
selected suggestion
this point we're also going to wipe the
suggestions list by setting it to be an
empty array as we don't want to still
show it when the user has just selected
an item
finally we need this to fire when a
suggestion is clicked on
so we're going to go down to the li for
a suggestion item and we're going to add
an on click event handler and we're
going to add an arrow function in there
and this is going to call
this dot suggestion selected with the
suggestion text for this li
we should now be done and everything
should work
now as we type it filters the list and
when we make our selection it populates
the text box so that's a success there
are a number of ways to handle css and
react today i'm going to show you the
simplest
you see here we have our app.css file
this came with create react app
and then if we go into our components
our app components javascript file we
import it just like we would a
javascript module not forgetting to add
the dot css extension this part's very
important
now looking in the browser and viewing
the source
we go into the head section
and we scroll down a bit
and there's this style tag here and
within it we see the contents of
app.css what's happening here is that
create react app has set up a webpack
loader for us
webpack is a commonly used javascript
build tool anyway this loader is
intercepting imports of files based on
the css extension it is then adding code
to add a style tag into the web page
using javascript and putting the
contents of all the imported css files
in here that's what happened with
app.css
so let's add our own css file
so we add a new file for our css
autocompletetext.css
within that we're going to add a class
autocomplete text
for now we're just going to put a width
of 100 on it
next we go to our component
and we need to import
autocompletetext.css
remember the.css extension
this now ensures that the css we wrote
shows up in the head of the document
just like with app.css
we can now apply the class we added to a
react element so we're going to apply it
to the wrapper div
now one thing to note this is very
important in jsx you can't just use the
class attribute because it's a reserved
word in javascript so you can't put just
that instead we have to use class name
uppercase on then but this acts just
like the class attribute in html so we
add our autocomplete text class in there
let's check that in the browser
so we can go to the head
and we can see the style has been added
there
looking at the finished product we can
work out what we need to do in terms of
styling firstly let's take the width
since this is a reusable component we
want a flexible width i think the best
way to achieve this is to make
everything 100 width then when someone
uses the component they can put in a
fixed width container in order to
dictate the final width of the component
now let's look at the border
so we have a grey border with a drop
shadow
my first thought was to put a border
around both the text input and the ul
that appears with the suggestions
the main problem with this is that if we
put a border and drop shadow on both
elements they would overlap at the
bottom of the text input and the top of
the ul
the simplest solution is just that the
container div has a border and a drop
shadow while the ul and text have none
this way when just the text box is shown
the border wraps that
when the suggestion list is also shown
it wraps both components
so let's make those changes now
the width of our container is already
100
so let's add a new selector for the text
input and give that a width of 100
2.
we then add a
gray border to our container
and then we want to drop shadow on it
too so we add some code from that now i
just generated this with an online tool
you can google css box shadow generator
and you'll find a similar tool
and we take off the border from the
input
so we're going to go into our app
component now
and we're going to wrap the text box
in a div with the class name of app
hyphen component
then we go back to app.css
and we do a selector for app hyphen
component as a class
and we're going to put some margin on
the top of it because we just want a bit
of space between the top of the browser
and the component
and then the margin the sides is going
to be auto to center it and we give it a
width of 600 pixels this is to constrain
the size of our reusable component from
outside of the component so
once we finish that we'll save and have
a look in the browser
taking a look at this we see that the
text in the list is centered we want it
left aligned also we want to get rid of
those bullet points let's do that now
so i'm just going to give the entire div
and also the input a consistent text
style so they just look the same
i'm now going to put in a new selector
for the ul
and with list style type set to 9 i get
rid of the bullets
and i align the text to the left
if we have a look at our elements we can
see the alignment is a bit off between
the text input and the list and there's
this funny thing going on with the right
hand side of the text box
um there's a couple of things going on
here
we need to use border box box sizing on
it otherwise the text input can end up
being more than 100 width of its parent
both the text input and the list items
should also have consistent padding
finally there's also a small you
probably can't see it but there is a
small gap between the top of the ul and
the bottom of the text input that throws
things off just a little bit this is
caused by the new line between the two
in the markup this can be fixed by using
the before pseudo selector
first we'll take away all the margin and
padding on the ul element we won't be
needing that
then we're going to add a consistent
margin and padding to both the li and
text input so we add a new selector of
the li
put the padding in there
and then put the same padding on the
text input
and we need to also add to that
box sizing and set it to border box for
the text input so it doesn't get more
than 100 in width
finally we're going to add a pseudo
selector for our ul
this is the before sudo selector we're
going to use
and it just allows us to remove the
white space before the ul
so we're going to send the content to be
an empty string
i also want to remove this blue
highlighting when the text box is in
focus this is very simple to do we just
add outline none to the text input
things are looking really pretty good
now
we actually do want to border at the top
of the ul though just to separate it
from the text input we also want to make
the list of items look clickable
we can do this by adding a cursor style
and some hover styling to the uis
so we add a border to the top of the ul
that's of course one pixel solid grey
and we set cursor to pointer on the li
so that the cursor has a little hand on
hover so it looks like a link something
we can click
then we're going to add a new selector
and we're going to use the hovo sudo
selector on the li selector
and then on hovered we're going to give
all the allies a background just sort of
a light gray background and an underline
to emphasize this to the user just to
emphasize that they're selectable
so yeah that all looks really good
i want some good data for our
suggestions so i'll get a list of all
the countries in the world
i google for it
and there's actually a text file for it
on github which is perfect
so i click view raw
and i copy all of them
we want the countries to be an array
so i create a new module countries.js in
src
and we simply paste in the entire list
and we're going to export it from the
module as the default export
i'm going to wrap it in backticks so it
can be multi-line as opposed to say
single or double quotes
and make sure there's no space at the
beginning or the end of the backticks
and then i do a dot split on the new
line character
and this will make it an array one line
or country in this case per item
the module now exports an array of
country names so if we go to our
component we have an array called this
dot items which contains the hard-coded
items names in this case we need to
transform this into a prop
props in react are a way to get data
into a component in order to make it
configurable you pass props to a react
element just like an html attribute
so if we have a look at the text input
down here
we use two props on that one is value
one is on change so this is just how you
get props
into a react element
and you can see up here the props are
passed to the constructor
we then pass them to super and after
that they can be accessed via an object
this dot props from anywhere in the
class
so we remove this dot items from the
constructor we don't need it anymore
and we use this variable in the function
on text change
where we filtered these items to get the
suggestions based on what the user typed
so let's destructure this dot props to
get a prop called items
and then we use that in place of this
dot items
now we need to go to the app component
where we actually used the text box and
passed in the countries as a prop called
items
so first we need to import our countries
from the countries module we created
then we add items as a prop just like an
attribute
and give it the value of countries in
curly braces
so now the text box has our list of
countries available
but what happens if we wanted to add
another text box with different items on
the same page we simply add another
autocomplete text tag
this one will set the items to be an
array of names we'll just hard code the
array straight in the curly brackets
straight into the prop items
we now have two auto complete text boxes
they're a bit squished together so let's
just add a bit of space in here
so now we've got two auto complete text
boxes on one page each has its own
internal state both has its own list of
items so we've created a truly reusable
component
if you want to progress to building
entire apps in react instead of just
components see the link to my course
learn react and redox from beginner to
paid professional in the video
description