Home > Software engineering >  React array map not updating when state array is updated
React array map not updating when state array is updated

Time:08-03

I have an object dashboard stored in state. Dashboard has a groups attribute that's an array of objects.

To update the groups, I added a callback

// This is all in DashboardContext (useDashboard)
const [dashboard, setDashboard] = useState(props.dashboard);

const addDashGroup = (group) => {
    const newData = {
        ...dashboard,
        groups: [
            ...dashboard.groups,
            group,
        ]
    }
    setDashboard(newData);
}

Then, I map it to use.

// This is used in a component that can see the `dashboard` variable with `useDashboard`
{dashboard !== undefined && dashboard.groups.length > 0 &&
    dashboard.groups.map((g, i) => <DashGroup key={g.id} index={i} group={g}/> )
}

However, when dashboard gets updated with the new groups, it doesn't update the component that uses dashboard.groups to map.

How can I get that component to update when dashboard.groups gets updated?

Edit 1

How I call the update callback:

// Part of the dashboard context.  Initial dashboard passed in as prop, then updated as needed.
const { dashboard, addDashGroup } = useDashboard();

// RTK-Query mutation
const [createDashGroup, {data: addedGroup, isLoading, error}] = useCreateDashGroupInDashboardMutation();

// Query above gets fired off when the form submits.  If it's successful, `addedGroup` gets populated (previously undefined).
useEffect(() => {
    console.log('created', addedGroup);
    if (addedGroup) addDashGroup(addedGroup);
}, [addedGroup]);

CodePudding user response:

Test update the state with:

const addDashGroup = (group) => {
    setDashboard((old)=> {
        return {
        ...old,
        groups: [
            ...old.groups,
            group,
        ]}
    );
}

CodePudding user response:

Try it with one extra state

const [dashboard, setDashboard] = useState(props.dashboard);
const [extra, setExtra] = useState(0);

const addDashGroup = (group) => {
    const newData = {
        ...dashboard,
        groups: [
            ...dashboard.groups,
            group,
        ]
    }
    setDashboard(newData);
    setExtra(extra 1)
}

with setTimeout

const [dashboard, setDashboard] = useState(props.dashboard);

const addDashGroup = (group) => {
    const newData = {
        ...dashboard,
        groups: [
            ...dashboard.groups,
            group,
        ]
    }
    setTimeout(() => {
      setDashboard(newData);
    }, 1000)
}

  • Related