React子组件访问Prop出现'Cannot read properties of undefined'错误的解决方法
问题修复方案
问题原因
组件首次渲染时,filesList是初始的空数组[],此时props.prop[0]为undefined,直接访问.name会抛出类型错误;而JSON.stringify(undefined)仅返回undefined,不会触发报错。后续异步请求完成后filesList更新,组件重新渲染就能正常读取,但首次渲染会出现报错。你提到的注释后再取消注释能正常运行,是因为此时数据已加载完成,重新编译时组件使用的是已有数据渲染,不会触发首次空数组的情况。
修复方法
方法1:使用可选链操作符(推荐)
直接在访问属性时添加?.,当props.prop[0]为undefined时,表达式会返回undefined,避免报错:
export default function FileDisplay(props) { return ( <div> <h2>LIST OF FILES</h2> <p>{JSON.stringify(props.prop)}</p> <p>-----------------------</p> <p>{JSON.stringify(props.prop[0])}</p> <p>-----------------------</p> <p>{JSON.stringify(props.prop[0]?.name)}</p> </div> ) }
方法2:条件渲染
判断数组是否有内容,再决定是否渲染目标属性:
export default function FileDisplay(props) { return ( <div> <h2>LIST OF FILES</h2> <p>{JSON.stringify(props.prop)}</p> <p>-----------------------</p> <p>{JSON.stringify(props.prop[0])}</p> <p>-----------------------</p> {props.prop.length > 0 ? ( <p>{JSON.stringify(props.prop[0].name)}</p> ) : ( <p>文件加载中...</p> )} </div> ) }
方法3:在父组件中控制渲染时机
给Home组件添加加载状态,等数据加载完成后再渲染FileDisplay:
export default function Home() { const { user, setUser } = useContext(UserContext); const [ filesList, setFilesList ] = useState([]); const [isLoading, setIsLoading] = useState(true); // 添加加载状态 useEffect(() => { const getData = async () => { const listFiles = await listAll(ref(storage, 'files')) const data = await Promise.all(listFiles.items.map(async (itemRef) => { const response = getMetadata(ref(storage, 'files/'+ itemRef.name)) return response })) setFilesList(data); setIsLoading(false); // 数据加载完成后关闭加载状态 } getData() }, []) return ( <div> <div> {!isLoading && <FileDisplay prop={filesList}/>} {/* 加载完成后再渲染 */} </div> </div> ) }
内容的提问来源于stack exchange,提问作者Lucas de Oliveira
相关产品推荐
相关产品推荐

