Lesson 1.4
This lesson will teach you the following:
- Lifting State
- Controlled Components
- Props handling
React has one-way data flow (i.e. unidirectional data flow) which means data will flow down from the parent component to the child components. There is a saying “React data flows down, and events flow up”.
Unidirectional data flow means that you send data from parent to child with props and you update data from child to parent with events. Other libraries such as Angular or Vue have two-way data flow (bidirectional data flow).
When you update the state, it may not immediately update your stateful variables. Instead, it actually just schedules, or enqueues an update to the component’s state. The reason for this behavior is it reduces the number of unnecessary component re-renders which improves performance.
The asynchronous nature of updating state can be a cause of bugs or unexpected behavior in a React app. The problem occurs that if you try to use the stateful variable immediately after you update it you may not get the most current state value.
If your state change is dependent on the current state, you can alleviate this issue by passing a function to your state setter function, rather than that a value or variable.
setCounter((prevCount) => {return prevCount+1});
When you pass a function to the setter function (setCounter), that function will receive the current state of the stateful variable (prevCount). The function that you pass to the setter function is called an updater function. The updater function is guaranteed to get the latest state value as a parameter.
If your stateful variable contains an object or array, you can replace the value by passing in a new object or array. But, if your new state depends on the old state, you’ll need to make a copy of the existing array or object, modify it, and then pass the copy of the array or object into the setter function.
Having a lot of components that each independently maintains their own state can increase the complexity of your app. To turn stateful components into stateless components, React developers use a technique called “lifting state up”.
This means that, instead of a component controlling its own state, you can have a component at a higher level in the hierarchy store the state. This state can then be passed down as props to the components that need it. This is very commonly done when sibling components need to share the same state as well. Lifting state up gives you the benefit of having fewer components that can cause your user interface to change, it makes your components more easily reusable, and makes your app easier to test.
- Open
/src/App.jsx
- Create new state variable named
todoList
with settersetTodoList
and default value of an empty Array - Pass
todoList
state as a prop namedtodoList
to theTodoList
component - Open
/src/TodoList.jsx
- Add
props
as a parameter to theTodoList
functional component - Change
todoList
to reference props instead of the hard-coded variable - Delete the hard-coded
todoList
variable - Run your application and view in browser
- Verify that your Todo List is now empty (no list items)
- Open
/src/AddTodoForm.jsx
- Create new state variable named
todoTitle
with settersetTodoTitle
- Modify the
<input>
element to be a controlled input- Add
value
prop equal totodoTitle
from component props - Add
onChange
prop equal tohandleTitleChange
function reference (we will declare this function in the next step)
- Add
- Above the
handleAddTodo
function, declare a new function namedhandleTitleChange
that takesevent
as a parameter- First, retrieve the input value from the
event
object and store in variable namednewTodoTitle
- Then, call the state setter
setTodoTitle
and passnewTodoTitle
- First, retrieve the input value from the
- In the
handleAddTodo
function, remove thetodoTitle
variable and updateonAddTodo
callback handler to pass ourtodoTitle
state variable instead - Run your application and view in browser
- Enter a new todo in "Add Todo" form, submit, and verify that the title appears below
- Open
/src/App.jsx
- Remove the
newTodo
state variable and the corresponding JSX that displays it - Declare a new function named
addTodo
that takesnewTodo
as a parameter- Call the
setTodoList
state setter and use the spread operator to pass the existing Objects in thetodoList
Array along with thenewTodo
Object
- Call the
- Change the value of the
onAddTodo
prop forAddTodoForm
toaddTodo
- Open
/src/AddTodoForm.jsx
- Inside
handleAddTodo
, update theonAddTodo
callback prop to pass an Object instead of a String; Object should have the following properties:-
title
: equal totodoTitle
-
id
: unique identifier (hint: useDate.now()
to generate a unique number)- Disclaimer: we are suggesting
Date.now()
for now as a placeholder for unique number generation, but in the future you should not use this
- Disclaimer: we are suggesting
-
- Inside
handleAddTodo
, remove thereset()
method and replace it with logic to reset thetodoTitle
state to an empty String - Run your application and view in browser
- Enter a todo in "Add Todo" form, submit, and verify item is visible in todo list
- Enter another todo, submit, and verify that two items are visible in todo list
- Open
/src/TodoList.jsx
and updateprops
to use destructuring - Open
/src/TodoListItem.jsx
and updateprops
to use destructuring - Open
/src/AddTodoForm.jsx
and updateprops
to use destructuring