I have a question about react array clearing

Issue

There is an array in the parent class(TodolistActivity), and the child class(TaskCallFunc) displays the elements in the array. When I use a.list= []; to clear the array, there is no clearing on the page

but a.list.length = 0 is ok. why?

Here is my code:

interface IListData {
    list: IActivityData[]
}

interface IActivityData {
    id: number,
    content: string,
    finish: boolean
}

export function TodolistActivity(activty: IListData) {
    const [acty, setActivity] = useState(activty);
    const [content, setContent] = useState('');
    const input_ref = React.createRef<HTMLInputElement>();
    const [selectCount, setSelect] = useState(0);
    
    const handleAdd = () => {

        if (input_ref.current) {
            if (input_ref.current.value === '') {
                alert("输入内容 不能为空!");
                return;
            }
            let id = acty.list.length;
            acty.list.unshift({ id: id, content: content, finish: false })
            let a = { ...acty }
            setActivity(a);
            input_ref.current.value = "";
        }

    }

    const calcuateSelect = () => {
        let a = acty.list.filter((v, i) => { return v.finish === true })
        setSelect(a.length);
    }

    const handleChange = (input: React.ChangeEvent<HTMLInputElement>) => {
        setContent(input.target.value);
    }

    const clearTask = () => {

        let a = { ...acty};
         a.list= [];
        //a.list.length = 0;
        setActivity(a);
    }

    return (
        <div>
            <input type='text' onChange={handleChange} ref={input_ref} />
            <button className="add task" onClick={handleAdd}>add task</button>
            <button className="clear task" onClick={clearTask}>clear task</button>
            {console.log(acty)}
            <TaskCallFunc data={acty} action={() => { calcuateSelect() }} />
            <br />
            <label htmlFor="">select{selectCount}/{acty.list.length}</label>
        </div>
    );
}

interface ItaskCell {
    data: IListData,
    action: () => void
}

function TaskCallFunc(taskData: ItaskCell) {
    const [data, setData] = useState(taskData);

    const HandleSlecet = (x: number) => {

        for (let index = 0; index < data.data.list.length; index++) {
            if (data.data.list[index].id === x) {
                let newState = { ...data };
                newState.data.list[index].finish = !data.data.list[index].finish;
                setData(newState);
                data.action();
            }
        }
    }
    const handleMap = () => {
        return data.data.list.map((v, i) => { return <li key={v.id}>{v.id}: {v.content} <input type="checkbox" checked={v.finish} onChange={() => { HandleSlecet(v.id) }} /> </li> });
    }

    return (
        <ul>{handleMap()}</ul>
    );
}

If you know the answer, please let me know thank you

Solution

TaskCallFunc component doesn’t "listen" for changes on the taskData prop to update the local copy stored in state. Use an useEffect hook with a dependency on taskData prop to update the state when it changes.

function TaskCallFunc(taskData: ItaskCell) {
  const [data, setData] = useState(taskData);

  useEffect(() => {
    setData(taskData);
  }, [taskData]);

  ...

Answered By – Drew Reese

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published