Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

useState not updating nested component

I have a function that uses a React hook to setup an initial array of users. The array subsequently gets rendered on the screen in the form of a list. Every time a button is clicked, a new element is appended to the end of the array. The update gets rendered to the screen correctly.

I also have another component that receives this array and should for now replicate the same behaviour but unfortunately the update does not get rendered. Code for both below.

I’ve read about shallow and deep copies but seems that’s not the cause because it works in the parent component correctly. I specifically initialise a new array in the setUsers hook to create a new reference. Code for both below:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Parent Component

import { Button, List } from "grommet";
import { Add } from "grommet-icons";
import { useState } from "react";

import Pending from "./Pending";

export default () => {
  const [users, setUsers] = useState([
    { key: 1, name: "Alan", amount: 20 },
    { key: 2, name: "Bryan", amount: 30 },
    { key: 3, name: "Chris", amount: 40 },
    { key: 4, name: "Eric", amount: 80 }
  ]);

  return (
    <>
      <Button
        primary
        label="Add"
        icon={<Add />}
        onClick={(e) => {
          const newUser = {
            key: Date.now(),
            name: "Adam",
            amount: 30
          };
          setUsers((oldUsers) => [...oldUsers, newUser]);
        }}
      />
      <List primaryKey="name" secondaryKey="amount" data={users} />
      <Pending data={users} />
    </>
  );
};

Nested Component

import { useState } from "react";
import { List } from "grommet";

export default (props) => {
  const [users] = useState(props.data);

  return (
    <>
      <List primaryKey="name" secondaryKey="amount" data={users} />
    </>
  );
};

Any ideas for what could be causing this. I’m new to React in general so would appreciate an explanation of why this happens on top of an actual solution.

>Solution :

You took the initial props.data and put in the state.
Later, when the props changed, you did not change the state – the users being rendered are still those from the state, rather than the updated ones from the props.
That is, if at first you have

props.data === users === [1, 2, 3, 4]

After adding a user you get

props.data === [1, 2, 3, 4, 5] !== [1, 2, 3, 4] === users

In a case like this, you don’t need a useState – just render the data from props directly. That was the component will update every time its props change.

import { List } from "grommet";

export default (props) => {
  return (
    <>
      <List primaryKey="name" secondaryKey="amount" data={props.data} />
    </>
  );
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading