Geek Culture
Published in

Geek Culture

Using prevState with React, basic and complex

Photo by Karla Hernandez on Unsplash

How to use the famous “prevState” to modify our React state without overriding it !

Let start with a basic exemple (the -famous- counter) :

With a fresh new React App:

import "./App.css";
import React, { useState } from "react";
const App = () => {
const [mySuperCounter, setMySuperCounter] = useState(0);
const handleIncrement = () => {
setMySuperCounter(mySuperCounter + 1);
setMySuperCounter(mySuperCounter + 1);
setMySuperCounter(mySuperCounter + 1);
};
const handleReset = () => {
setMySuperCounter(0);
};
return (
<div className="App">
<div>
<button
className="super-button"
type="submit"
onClick={handleIncrement}>
Incrementor
</button>
<button className="super-button" type="submit" onClick= {handleReset}>
State Resettor
</button>
</div>
<div>{mySuperCounter}</div>
</div>
);
};
export default App;

Ok here we have a basic component with a state “mySuperCounter”, and two button, one to increment, one to reset my state to 0.

If we look at the “handleIncrement” method we can think that the state will be incremented by 3 each time I click on my “Incrementor” button.

Instead of that we just increment by one. Why ? Cause our setState function will override the previous state to create a new one…So we’ll override 3 times our initial State by one, give us a magic result of ….one.

Now let’s have a look how we can add to the previous state :

I’ll just past my handleIncrement method here :

const handleIncrement = () => {
setMySuperCounter((prev) => prev + 1);
setMySuperCounter((prev) => prev + 1);
setMySuperCounter((prev) => prev + 1);
};

Here we go ! Now If we click on our “Incrementor” button we increment our counter by 3.

Why ? Because of our “prev” argument passed to the callback function of our setState.

In our case “prev” is equal to the previous State, so line by line we increment 0 by 1, 1 by 1, 2 by 1 => Result: 3

That’s for a basic example, let’s have a look on a more complex one !!

Add key/value from an array to an array of object:

Photo by Nick Fewings on Unsplash

Let’s simulate an API call with a promise:

// sections.jsconst mySections = () => {
return Promise.resolve([
{ id: 1, title: "My First Section" },
{ id: 2, title: "My Second Section" },
] );
};
export default mySections;

Then transform our App.js to make the call with a useEffect and store the result in a state:

// App.jsimport "./App.css";
import React, { useEffect, useState } from "react";
import mySections from "./sections";
const App = () => {
const [sections, setSections] = useState([]);
useEffect(() => {
const loadSections = async () => {
return await mySections();
};
loadSections().then((res) => {
setSections(res);
});
}, []);
return <div className="App"></div>;
};export default App;

Let’s create an other promise in an other file to simulate an other API call, we’ll receive data that we would like to dispatch in the sections above, depending on the section_id.

// tools.jsconst myTools = () => {
return Promise.resolve([
{ id: 1, title: "My Super first tools", section_id: 1 },
{ id: 2, title: "My Super second tools", section_id: 2 },
{ id: 3, title: "My Super third tools", section_id: 1 },
{ id: 4, title: "My Super fourth tools", section_id: 2 },
{ id: 5, title: "My Super fifth tools", section_id: 1 },
{ id: 6, title: "My Super sixth tools", section_id: 2 },
{ id: 7, title: "My Super seventh tools", section_id: 1 },
{ id: 8, title: "My Super eighth tools", section_id: 2 },
]);
};
export default myTools;

Then we have to modift ou App.js:

//App.jsconst App = () => {
const [sections, setSections] = useState([]);
useEffect(() => {
const loadSections = async () => {
return await mySections();
};
loadSections().then((res) => {
setSections(res);
});
const loadToolsIntoSections = async () => {
return await myTools();
};
loadToolsIntoSections().then((response) => {
setSections((prev) => {
return prev.map((section) => {
return {
...section,
tools: response.filter((tool) => {
return tool.section_id === section.id;
}),
};
});
});
});
}, []);
return <div className="App"></div>;
};
export default App;

Explanation:

We call the “loadToolsIntoSections” method, wich is an other API call simulation.

We re-use the setSections method and pass the “prev” argument to the callback. (we keep the previous state)

We map over the sections array to interact each object in it.

We use the spread operator to to create an other object, and we add an other key “tools”.

We use the response of ouf API Call to filter each tool where the section_id match with the id of the actual section.

By this way you can dispatch every tools inside their respective sections.

Hope this helps to understand how to use prevState easily !

--

--

--

A new tech publication by Start it up (https://medium.com/swlh).

Recommended from Medium

A BASIC INTRODUCTORY GUIDE TO JAVASCRIPT IN WEB DEVELOPMENT [ Episode I]

Make scalable Cron jobs in Node js

Welcome To Web Scraping

How To Implement Drawing In React App

Deploy React Apps with Apache2, how and why?

Credits to https://res.cloudinary.com/practicaldev/image/fetch/s--t-P9YAGr--/c_imagga_scale,f_auto,fl_progressive,h_900,q_auto,w_1600/https://techstream.org/images/img/Final-steps-with-React-JS-App.jpg

Serverless + Express + DynamoDB (LocalStack)

A How-to Guide on Making an Animated Loading Image for a Website

4 Tips Beginner React Devs Should Follow

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
AntoineGGG

AntoineGGG

Clean Code Padawan

More from Medium

React Dropzone and upload images Part 12 Styling the react dropzone

Getting started with Cypress.io

React Virtual DOM, Reconciliation and Fiber Reconciler

How To Easily Test Your React Components