Skip to content
Advertisement

Not being able to print an array

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>
  );
}

Advertisement

Answer

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.

Advertisement