【发布时间】:2021-04-25 03:40:50
【问题描述】:
我要做的是用 axios 获取数据,然后将数据设置为 state。一旦结束,我将加载标志设置为 false 并有条件地渲染一个子组件,我想在其中检索数据数组的第一项的属性。
这是我的自定义钩子代码。我只是获取产品数据并设置数据。
export const useAllProducts = () => {
// const { showMessage } = useMessage();
const [loading, setLoading] = useState(false);
const [products, setProducts] = useState<Array<Product>>([]);
const getProducts = useCallback(() => {
setLoading(true);
axios
.get<Array<Product>>("http://localhost/api/admin/products")
.then(res => setProducts(res.data))
.catch(() =>
console.log('failed to fetch product data')
)
.finally(() => setLoading(false));
}, []);
return { getProducts, loading, products };
};
这是我的产品页面。加载完成后,它会以产品数据为道具呈现产品列表组件。
const ProductPage: React.FC = () => {
const { getProducts, loading, products } = useAllProducts();
useEffect(() => {
getProducts();
}, []);
return (
<CommonLayout title="product list">
{!loading ?
<ProductList title="product" data={products as Product[]} /> : 'loading'
}
</CommonLayout>
);
}
export default ProductPage;
在此之后,在产品列表组件中,我希望能够像这样访问属性名称。
const ProductList = <T,>(
props: React.PropsWithChildren<Props<T>>
) => {
console.log(props)
const classes = useStyles();
Object.keys(props.data[0])
return (
<div>
a
</div>
);
}
但是,它给了我如下错误。
未捕获的类型错误:无法将未定义或 null 转换为对象 在 Function.keys () 在 ProductList (app.js:12755) 在 renderWithHooks (app.js:33809) 在 mountIndeterminateComponent (app.js:36488) 在 beginWork (app.js:37602) 在 HTMLUnknownElement.callCallback (app.js:19194) 在 Object.invokeGuardedCallbackDev (app.js:19243) 在 invokeGuardedCallback (app.js:19298) 在 beginWork$1 (app.js:42209) 在 performUnitOfWork (app.js:41160)
我什至先检查了数据的长度,但没有运气。
有没有人知道为什么条件渲染不起作用?
编辑1
这是我在 cmets 之后更改的自定义挂钩代码。逻辑似乎很好..
export const useAllProducts = () => {
const [loading, setLoading] = useState(true);
const [products, setProducts] = useState<Array<Product>>([]);
const getProducts = useCallback(() => {
axios
.get<Array<Product>>("http://localhost/api/admin/products")
.then(res => {
setProducts(res.data)
setLoading(false)
})
.catch((error) =>
console.log(error)
)
}, []);
return { getProducts, loading, products };
};
编辑:2
我的简化产品列表组件代码。
const ProductList = <T, >(
props: React.PropsWithChildren<Props<T>>
) =>{
console.log(props)
const classes = useStyles();
Object.keys(props.data[0])
//The error is happening here//
【问题讨论】:
-
不应该是
!loading ? <ProductList /> : "loading"吗? -
你的条件应该是
loading ? "Loading": <ProductList title="product" data={products as Product[]} /> } -
我想我知道问题所在,默认的
loading值是false,所以它会抛出该错误,因为创建组件时products仍然为空,尝试将其设置为@987654331 @像这样const [loading, setLoading] = useState(true); -
从
finally块中删除setLoadingfalse。如果出现错误,组件仍然会呈现。 -
@Medi 这似乎是正确的模式,无论发生什么——错误或数据,您必须将
loading设置为 false,因为无论是否有错误都完成了加载。要处理错误,您有 OP 可以在控制台中看到的catch块。
标签: javascript reactjs typescript