仅在 useEffect 之后使用数据

using the data only AFTER useEffect

我有一个 React 组件(用 Typescript 编写)如下。

在这个组件中,我尝试读取我有数据的 excel,然后使用数据渲染组件

由于在useEffect为运行之前没有读取数据,所以将menuData初始化为null.

读取数据工作正常,我的 menuData 没有错误。

但是,第 let meals = [...new Set(menuData.map((item: menuItem) => item.Meal))]; 行抛出错误 TypeError: menuData is undefined。我认为这是因为当 menuData 仍为 undefined(在 useEffect 运行s 之前)时执行此行。

如何克服这个错误?换句话说,在 useEffect 具有 运行 之后如何 运行 let meals = [...new Set(menuData.map((item: menuItem) => item.Meal))];?

我想将此行保留在 useEffect 之外,因为需要对对象的 menuData 数组执行更多数组函数(映射、过滤器等)。

export const CategoryItems = ({ toggled }: CategoryItemsProps) => {
  
const [menuData, setMenuData] = useState<menuData | undefined>(undefined);

   /*Code to read the excel with menu items once the page is loaded.
  The sheet will be read only once*/
  useEffect(() => {
    let url = "data.xlsx";
........
....
.....
      setMenuData(XLSX.utils.sheet_to_json(worksheet, { raw: true }));

  }, []);

 let meals = [...new Set(menuData.map((item: menuItem) => item.Meal))];

  return (
    <div className={`category-items ${toggled ? "theme-dark" : "theme-light"}`}>
.
.
.
    //additional code to render the component based on the variable `meals`
.
.
.
      </div>
    </div>
  );
};

只需将您的状态初始化为一个空数组即可。

const [menuData, setMenuData] = useState<menuData>([]);

应该可以!

就我个人而言,如果数据尚未到来,我喜欢退出渲染阶段,因为 useEffect 内的 setState 无论如何都会导致另一个渲染。 17=]

if (!menuData) return null;
let meals = [...new Set(menuData.map((item: menuItem) => item.Meal))];

null 只是一种不渲染任何东西的简单方法..

我喜欢这种方式,如果你发现 useEffect 有时会花费一些时间,而不是 returning null,我们也许可以 return 某种形式的加载指示器..

if (!menuData) return <div className="loading">Loading..</div>;
let meals = [...new Set(menuData.map((item: menuItem) => item.Meal))];

将数据初始化为空的东西是可行的,但是你有点松散了一些隐式状态,如果你的渲染结构更复杂,我发现提前退出更容易推理..