React提交Firestore后报TypeError: Cannot read property '0' of undefined如何修复
报错根因
报错的核心原因是location.state为undefined时,直接访问data[0]触发了类型错误。location.state属于路由跳转时的临时传参,仅在从上一页正常跳转过来的首次渲染时存在,以下场景都会导致它丢失:
- 页面手动刷新
- 用户直接通过URL访问编辑页,没有从上一页跳转触发传参
- 提交完成后组件重新渲染/挂载时,路由没有保留state参数
你提交成功后才触发报错,大概率是提交操作触发了组件重新渲染,此时location.state已经被清空,代码再次执行到const id = data[0]就抛出了错误。另外你原有代码中Ref.set前没有加await,异步操作没有等待执行完成也可能带来时序问题。
修复方案
- 给
location.state加非空校验和兜底默认值,同时把需要用到的参数转存到组件本地状态,避免每次渲染都直接读取路由临时参数 - 如果提交完成后不需要留在编辑页,操作成功后直接跳转到列表页,避免当前组件二次渲染触发报错
- 增加非法进入编辑页的拦截逻辑,没有拿到有效参数时自动跳回列表页
修改后的完整代码如下:
const Edit = () => { const location = useLocation(); // 可选链+默认值兜底,避免state为空时报错 const data = location.state ?? []; // 把id也存到本地状态,不需要每次渲染从location取 const [id, setId] = useState(data[0] ?? ''); const [productName, setProductName] = useState(data[1] ?? ''); // 没有拿到有效id时直接跳回列表页,拦截非法访问 useEffect(() => { if(!id) { // 此处替换为你的产品列表页实际路由 window.location.href = '/product/list'; } }, [id]) const handleSubmit = async (event) => { event.preventDefault(); try { const Ref = firestore.collection("products").doc(id); // 补充await等待异步操作执行完成 await Ref.set( { productName, }, { merge: true } ); alert("Successfully updated"); // 提交成功后跳回列表页,避免当前组件重复渲染 window.location.href = '/product/list'; } catch (err) { console.log(err); } }; return ( <div> <Container> <form onSubmit={handleSubmit}> <FormControl> <TextField id="input" margin="dense" type="text" label="Product Name" value={productName} color="secondary" fullWidth onChange={(e) => setProductName(e.target.value)} /> <Button type="submit" > Update </Button> </FormControl> </form> </Container> </div> ); }; export default Edit;
内容的提问来源于stack exchange,提问作者JS3
相关产品推荐
相关产品推荐

