首页 > 解决方案 > 将数组设置为 null 然后在 useEffect React 中更新它

问题描述

我是反应新手。我有一个 MealList 组件,我将一组 props 传递到该组件,它基于该组件进行数据调用并更新一组餐食,我将其显示在表格中。

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>

    )
};

我面临的问题是,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])
        });

但这也不起作用。

标签: javascriptreactjsreact-hooks

解决方案


这是一个示例(试图模仿您的代码):

Stackblitz 演示:https ://stackblitz.com/edit/react-hooks-usestate-svnmpn?file=MealList.js

问题在于数据突变,如果您希望新的更改重新呈现您的组件并应用更新,则必须保持不变。

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

  useEffect(() => {
    const fetchMeals = async (userId, fromDate, toDate, fromTime, toTime) => {
      return await new Promise(res =>
        setTimeout(
          _ =>
            res({
              data: [
                { id: 1, name: "sphagetti" },
                { id: 2, name: "salad" },
                { id: 3, name: "soup" },
                { id: 4, name: "bacon and eggs" }
              ]
            }),
          2000
        )
      );
    };
    fetchMeals(1, "date1", "date2", "time", "time2").then(r =>
      setMeals([...r.data])
    );
  }, [props]);

  return (
    <div style={{ width: "70%" }}>
      {!meals.length && <p>wait 2 seconds...</p>}
      {meals.map((meal, index) => (
        <div key={meal.id} count={index + 1} meal={meal}>
          {meal.id + ". " + meal.name}
        </div>
      ))}
    </div>
  );
};

推荐阅读