In react state management is one of the most important and challenging task and basically it is half react, and the other half is the beauty part consisting of html and css which renders in the browser.
What is state?
State is nothing but encapsulated data where you store assests that are persistent between the components rendering. Insimple terms state is just a javascript data structure like linked list, trees or graphs, if a user changes the state by interacting with your application the ui changes and re renders because old state is changed with new state. In order to manage these states in react developers use react hooks or management libraries like redux. In this article let's take a closer look on react hooks like useState and useReducer.
React Hooks
React hooks are functions that are used to access objects state and lifecycle methods from inside a function using event listeners. This feature is introduced in react 16.8, now let's take a closer look in different react hooks.
Use state hook
Use state is hook that allows user to add a new state to the functional component to understand this let’s use counter as an example. Here is a simple counter example created using vite+react:
Code:
import { useState } from 'react'
import './App.css'
function App() {
let[count, setcount] = useState(0);
function addOne (){
}
return (
<div className='App'>
<button onClick={addOne}>Count = {count}</button>
</div>
)
}
export default App
In this example our goal is to implement a counter that gets incremented by one whenever user clicks on the button. Use state is a function that takes two elements one is the variable and a setter function to update the state of the variable. Now in order to increment the counter when ever the user clicks button we use onclick event listener which triggers addOne function,now lets fill out the logic in the function.
Generally what every beginner thinks is to simply do a count++ which will indeed increment the variable count but it is wrong wo understand why it is not increment is really important as it defines the core use of state management in react. Here when user clicks the button a count variable copy is sent but not the real variable, so whats happening is every time a user clicks the counter a value is sent to function but not the reference to the original variable so only the value is getting updated and staying inside the function addOne but not updating orreturning the new state, in order to solve this we call the setcount function to set the state again to the new value. What set count function does is it takes the previous state value and return the new state value based on that now the component rerenders as the state is changed.
Code:
import { useState } from 'react'
import './App.css'
function App() {
let [count, setcount] = useState(0);
function addOne (){
setcount(count+1)
}
return (
<div className='App'>
<button onClick={addOne}>Count = {count}</button>
</div>
)
}
export default App
What this feature does is allows react to use the component multiple times as each components acts as an object which has its own data that is stored in it which is the main feature of react, to understand this lets rename our App() to counter and re write this code with another app() which takes the counter as a functional component which reduces repetition of code.
Code:
import { useState } from 'react'
import './App.css'
function Counter() {
const [count, setcount] = useState(0);
function addOne (){
setcount(count+1)
}
return (
<div className='App'>
<button onClick={addOne}>Count = {count}</button>
</div>
);
}
function App(){
return (
<div>
<Counter/>
<Counter/>
</div>
)
}
export default App;
Here we changed the variable assignment to const from let as it will make sure that no body can change the count value with improper assignments to count.
use reducer
In order to understand use reducer let's understand Array.reduce method. Here is a simple example of reduce method where we get sum of all numbers in an array.
Code:
const numbers = [10,20,30]
const total = numbers.reduce(( cv, n) => {cv+n},0);
console.log(total);
The reduce( ) method executes a reducer function for the array element the reduce() methods method output is a single value which is the functions accumulated result on the array. The syntax of reduce() method is array.reduce(function (total, currentValue, currentIndex, arr), initialValue). Here initial value and currentindex are optional.
Things to remember when implementing reduce() method:
At the first callback, there is no return value from the previous callback.
Normally, array element 0 is used as initial value, and the iteration starts from array element 1.
If an initial value is supplied, this is used, and the iteration starts from array element 0.
use reducer() is hook similar to iseState() hook that allows to implement custom state logic, if you want to keep track of multiple states for different scenarios useReducer is helpful for example adding names on list based on wether the user input is first name or last name or to implement a todo list with completed button. The method takes an initial state the The reducer function contains your custom state logic and the initial State, it can be a simple value but generally will contain an object. The useReducer() hook returns a state and an dispatch method, in the dispatch method we can give an object containing type of action and payload. Here is an example:
Code:
function NameList(){
const [state, dispatch] = useReducer( (state, action)=>{
switch(action.type){
case "SET_NAME":
return{...state, name: action.payload}
case "ADD_NAME":
return{...state, names: [...state.names,state.name], name:""}
}
} , {
names: [],
name: ""
})
return(
<div>
<ul>
{state.names.map((name,index) => (
<li key={index}>{name}</li>
))}
</ul>
<input type='text' value={state.name} onChange={(e) => {dispatch ({type:"SET_NAME", payload:e.target.value})}}></input>
<button onClick={() => {dispatch({type:"ADD_NAME",})}}> Add Name</button>
</div>
)
}
In the above example we created a component called nameList, here we use use reducer to manage state for different type of actions here action has a type which is ‘SET_NAME’ and ‘ADD_NAME’, based on the button clicked or name typed we determine what logic need to implement with payload that is sent using dispatch method.’
If you have liked the article please follow me on hashnode or bokmark my blog for further articles like this