仅在 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))];
将数据初始化为空的东西是可行的,但是你有点松散了一些隐式状态,如果你的渲染结构更复杂,我发现提前退出更容易推理..
我有一个 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))];
将数据初始化为空的东西是可行的,但是你有点松散了一些隐式状态,如果你的渲染结构更复杂,我发现提前退出更容易推理..