将数组设置为 null 然后在 useEffect React 中更新它

Mel*_*art 7 javascript reactjs react-hooks

我是 React 的新手。我有一个 MealList 组件,我正在向它传递一组道具,基于它进行数据调用并更新我在表格中显示的膳食数组。

const MealList = (props) => {
    const [meals, setMeals] = useState([]);

    useEffect(() => {

        const fetchMeals = async (userId, fromDate, toDate, fromTime, toTime) => {
            ...
            return resp;
        };
        fetchMeals(localStorage.getItem('user_id'), props.fromDate, props.toDate, props.fromTime, props.toTime).then(r => {
            setMeals([...meals, ...r.data])//The fetched data is stored in an array here.
        });
    }, [props]);
    console.log(props.fromDate);
    return (
        <div style={{width: '70%'}}>
            ...
            <Table striped bordered hover>
                <thead>
                <tr>
                    ...
                </tr>
                </thead>
                <tbody>
                {meals.map((meal, index) => (<Meal key={meal.id} count={index +1} meal={meal}/>))}//And displayed here
                </tbody>
            </Table>
        </div>

    )
};
Run Code Online (Sandbox Code Playgroud)

我面临的问题是,setMeals([...meals, ...r.data])每次通过道具更新 MealList 时,使用传播语法附加到现有列表。

我的问题是如何将膳食数组设置回 null,然后仅更新新值?我试过这个:

fetchMeals(localStorage.getItem('user_id'), props.fromDate, props.toDate, props.fromTime, props.toTime).then(r => {
            setMeals([]);
            setMeals([...meals, ...r.data])
        });
Run Code Online (Sandbox Code Playgroud)

但这也行不通。

650*_*502 2

如果你想要相同的拼接效果,你应该使用

 setMeals(r.data.slice());
Run Code Online (Sandbox Code Playgroud)

否则,将r.data传递对的引用,如果该对象在调用后发生变化,则会产生影响setMeals

当您将数组传递给 Javascript 中的函数时,该函数不会收到数组的副本,而是收到对您传递的原始对象的引用。例如:

 let x = [1,2,3], y = null;

 function foo(xx) {
     y = xx;
 }
 foo(x);
 console.log(y); // gives [1, 2, 3]
 x[1] = 99;
 console.log(y); // gives [1, 99, 3]
Run Code Online (Sandbox Code Playgroud)

fetchMeals显然,(我们没有看到)中的代码重用了数组r.data,如果您不进行复制,就会产生问题。我可能会将其归类为一个(设计)错误,因为fetchMeals给定的界面我希望得到一个新的答案,而不是我必须复制的重用答案。

另请注意

x.slice()
Run Code Online (Sandbox Code Playgroud)

是相同的

[...x]
Run Code Online (Sandbox Code Playgroud)