Home > other >  React updating useState array not causing element refresh
React updating useState array not causing element refresh

Time:02-02

I am unable to trigger the component to update when the viaList state is changed. If anyone could help, please <3

I don't want to append these children if possible.

import React, { useEffect, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';

function BookingForm() {
  const [viaList, setViaList] = useState([]);

  function addViaLocation() {
    const arr = viaList;

    arr.push(
    <li key={uuidv4()}>
      <label className="form-label">
        Via Location
      </label>
    </li>)

    setViaList(arr);
  }

  return (
    <>
      <button onClick={addViaLocation} className="button-standard primary" type="button">
        Add Additional Location
      </button>
      <ul>{viaList.length > 0 && viaList.map(item => item)}</ul>
    </>
  );
}

export default BookingForm;
  • Separating the functionality into a separate component
  • Triggering the update using props
  • Regular DOM stuff (appending doesn't fit our use case)

CodePudding user response:

You need to create a new array such that React understands it has changed. If you only push to the old viaList it will still hold that viaList === previousViaList. Instead create a new array, e.g. with the spread operator:

  function addViaLocation() {
    const newElement = (
    <li key={uuidv4()}>
      <label className="form-label">
        Via Location
      </label>
    </li>)

    setViaList([...viaList, newElement]);
  }

CodePudding user response:

Fixed it...

I was doing the following (just longer):

setViaList([...viaList, <li>STUFF</li>])

I had to update the state array using a callback instead:

setViaList(viaList => [...viaList, <li>STUFF</li>])

CodePudding user response:

the component only render when the prev value of a hook is different from the new one and this is not the case here

const arr = viaList;

trying to update arr is like trying to update viaList which not possible so you are giving the same value to setViaList therefore the component does not render.

but when you create a copy you can update it:

const arr = [...viaList];

CodePudding user response:

import React, { useEffect, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';

function BookingForm() {
  const [viaList, setViaList] = useState([]);

  function addViaLocation() {
    const arr = [...viaList];

    arr.push(
    <li key={uuidv4()}>
      <label className="form-label">
        Via Location
      </label>
    </li>)

    setViaList(arr);
  }

  return (
    <>
      <button onClick={addViaLocation} className="button-standard primary" type="button">
        Add Additional Location
      </button>
      <ul>{viaList.length > 0 && viaList.map(item => item)}</ul>
    </>
  );
}

export default BookingForm;

You can Create a shallow Copy of the Array by spreading the current state array and then pushing the new data and update state with the shallow copy

  • Related