React.js child component not updating when props are changed through the parent

The idea of my program is to generate a large list of tasks based off of user input. The tasks will then complete one by one and each will display it’s status as the tasks are asynchronous. I’m trying to use a parent class to control when each task is fired to prevent collisions. My structure is Output controls the list of ListItems and ListItem showing the title of the task and status. The classes look like:

Output.tsx

import { useState, useEffect } from 'react';
import styles from '../styles/Output.module.css';
import ListItem from './ListItem';
import OutputType from '../types/OutputType';
import Test from './Test';
export default function Output({ keywords, locations }:OutputType) {
    const [ statuses, setStatuses ] = useState([]);
    const [ pointer, setPointer ] = useState(0);
    
    const flattenIndex = (row:number, col:number, max_col:number) => {
        return ((row*max_col)+col);
    }

    const nextTask = () => {
        switch(statuses[pointer]){
            case "queued":
                const new_arr = statuses;
                // @ts-ignore
                new_arr[pointer] = "inProgress";
                setStatuses(new_arr);    
                break;
            case "inProgress":
                break;
            case "completed":
                setPointer(prev => prev+1);
                break;
            default:
                console.log(`error: unknown value ${statuses[pointer]}`);
        }
    }
    
    useEffect(() => {
        // initialise statuses
        const arr = [];
        for(let i = 0; i < keywords.length; i++)
            for(let j = 0; j < locations.length; j++)
                arr.push("queued");

        //@ts-ignore
        setStatuses(arr);
        // eslint-disable-next-line
    },[keywords.length]);

    useEffect(() => {
        nextTask();
        console.log("callback", statuses);
        // eslint-disable-next-line
    }, [statuses]);

    // @ts-ignore
    const updateStatus = (index:number, status:string) => setStatuses(prev => prev[index] = status);
    return (
        <section id={styles.output}>
            {keywords.map((keyword:string, index1:number) => (
                locations.map((location:string, index2:number) => {
                    //@ts-ignore
                    const index = flattenIndex(index1, index2, locations.length);
                    return <ListItem 
                                key={index}
                                title={keyword+" "+location}
                                status={statuses[index]}
                                updateStatus={updateStatus}
                            />
                })
            ))}
            <Test />
        </section>
    )
}

ListItem.tsx

import { useEffect } from 'react';
import styles from '../styles/ListItem.module.css';
import ListItemType from '../types/ListItemType';
export default function Listitem({ title, status, updateStatus }:ListItemType) {
    const getIcon = (status:string):string => {
        switch(status){
            case 'queued':
                return '❯';
            case 'inProgress':
                return '↻';
            case 'completed':
                return '✔'
            default:
                return '✖';
        }
    }
    useEffect(() => {
        console.log(status);
    }, [status])
    return (
        <div className={styles.list_item}>
            <p className={`${styles.icon} ${styles[status]}`}>{getIcon(status)}</p>
            <p className={styles.status_text}>{title}</p>
        </div>
    )
}

Basically with my statuses useState I have a giant array of what the status of the tasks are which I’m then passing through to the child component ListItem. I then want the status to be able to update the icon to represent that change. When I currently run it, it does the following: Screenshot of the program output. As you can see in the console it’s outputting correctly with “inProgress” being in the first position, however this doesn’t seem to update the child component at all. As nothing prints when I use a useEffect with status, and the icon doesn’t change from an > to a spinning arrow. Is it because I’m using an array? I’ve gone through lots of different stack overflow posts, but I still can’t seem to get it to work, so I’m sure it’s something obvious I’m missing. Any help would be greatly appreciated.

Answer

The problem seemed to be when I was trying to set the new state. I was copying the array, but I was copying it incorrectly, using:

const new_arr = statuses;

but in javascript you have to copy arrays with either:

const new_arr = [...statuses];

or

const new_arr = statuses.slice();

After I changed this everything seemed to work