i created empty array using the React State Hook, the array starts empty and i have 3 functions to (add to the array), (remove the last element of the array) and another to empty the array. The functions seems to work since i logged the result in the console. But when i want to print the array on a paragraph, the array does not show. Can someone give me some feedback? Thanks.
The code is below
import './counter.css';
import { useState } from 'react';
export default function HandleArray() {
const [inicial, handler] = useState([]);
function addElement(element) {
inicial.push('ok');
handler(inicial);
console.log(inicial);
}
function removeElement() {
inicial.pop();
handler(inicial);
console.log(inicial);
}
function reset() {
inicial.length = 0;
handler(inicial);
console.log(inicial);
}
return (
<div className='card text-bg-light border-success mb-3'>
<div className='card-header'>Welcome</div>
<div className='card-body'>
<h5 className='card-title'>Manipulate the array</h5>
<button type='button' className='btn btn-dark ' onClick={addElement}>
Insert Element
</button>
<button
type='button'
className='btn btn-danger'
onClick={removeElement}
>
Remove Element
</button>
<button type='button' className='btn btn-warning' onClick={reset}>
Reset array
</button>
//log the array
<p className='card-text'>{inicial}</p>
</div>
</div>
);
}
CodePudding user response:
In React, you shouldn't mutate state. Mutating state is an anti-pattern, not allowed, a big no-no (hope I was clear on this one). What you do, is you create a copy of your state, and call the handler with this new value.
For example:
function addElement(element) {
inicial.push('ok');
handler(inicial);
console.log(inicial);
}
Should be:
function addElement(element) {
const inicialCopy = [...inicial] //using spread operator to create a new array. You can create a new array using new Array, or any other way.
inicialCopy.push(element)
handler(inicialCopy)
}
This way, handler
was called with a new entity (a new array) so we are ok to go. There are other ways to do this. Let's do the next one using a callback.
function removeElement() {
handler((prevState)=>{
prevState.pop() // prevState now has 1 less element
return prevState
});
}
Same principle. You call handler
to update the new value.
Lastly, reset could just call handler
with an empty array.
function reset() {
handler([]);
}
Now, let's speak about two other issues. The first one is naming. When you use the useState hook, by convention, the naming would be something like this:
const [property, setProperty] = useState(initialValue)// which in your case:
const [initial, setInitial] = useState([])
Lastly, you placed console.logs
inside your functions. Those console.logs will log the OLD state. Not the new one.
If you want to have the new one, you need to wrap it in a useEffect
, and add inicial
to the dependencies array:
useEffect(()=> { console.log(inicial)}, [inicial]}
I hope it helps.