Let’s digest this harsh truth ➡️Updating array and objects is not so straightforward in React Js.
If you are thinking, you can directly use the inbuilt method of Array and object, and update your existing state, then that’s a wrong approach.
For instance –
❌arr.push() or arr.pop() is not the correct approach
📝Mutating a state directly is not recommended.
Watch Video Instead
❓Why we should not mutate the state directly?
Mutating the state directly will not help in re-render of your component. Also, in the case of a pure component, if you mutate the state directly, if you mutate the state the object reference will still be the same, hence it will create errors and bugs at a later point in time.
🤔How do we achieve mutability ?
Instead of mutating the array, what if we replace the original array with a new one that has the changes we want. In other words, we:
1. Make a copy of the original
2. Make changes to the copy
3. Replace the original with the copy
This is immutability.
Let understand this by code –
import "./App.css"; import { useState } from "react"; interface Data { id: number; name: string; like: number; dislike: number; } function App() { const [typedName, setTypedName] = useState<string>(); const [random, setRandom] = useState<number>(3); const [data, setData] = useState<Data[]>([ { id: 1, name: "himanshu", like: 0, dislike: 0, }, { id: 2, name: "shekhar", like: 0, dislike: 0, }, ]); const addData = () => { setRandom(random + 1); setData((prev: any) => [ ...prev, { id: random, name: typedName, like: 0, dislike: 0 }, ]); }; console.log(data); const handleSort = () => { setData([...data].sort((a, b) => b.like - a.like)); }; const handleDelete = (id: number) => { setData(data.filter((prev) => prev.id !== id)); }; const handleLike = (id: number, like: number) => { const new_data = data.map((item) => item.id === id ? { ...item, like: like + 1 } : item ); setData(new_data); }; const handleDislike = (id: number, dislike: number) => { const new_data = data.map((item) => item.id === id ? { ...item, dislike: dislike + 1 } : item ); setData(new_data); }; return ( <> <h2>Playing with object using hooks</h2> <div> <button onClick={handleSort}>Sort</button> </div> <input type="text" placeholder="add here" onChange={(e) => setTypedName(e.target.value)} /> <button onClick={addData}>Add</button> {data.map((ele) => ( <div key={ele.id} className="main_div"> <h2>{ele.name}</h2> <p>👍 - {ele.like} </p> <p>👎 - {ele.dislike}</p> <button onClick={() => handleDelete(ele.id)}>Delete</button> <button onClick={() => handleLike(ele.id, ele.like)}>Like</button> <button onClick={() => handleDislike(ele.id, ele.dislike)}> Dislike </button> </div> ))} </> ); } export default App;
Conclusion
Its not the you cannot update state directly, but it it not recommeded by react js .
So the best way is to make a copy of state , update it and then render it.
Hope you found the information helpful.