React.js获取接口数据时报Uncaught TypeError,硬编码数据无异常
问题分析
报错Cannot read properties of undefined (reading 'cameras')的核心原因有两个:
points初始值是空数组,组件首次渲染时points[0]为undefined,直接访问points[0].cameras会触发类型错误- 接口请求是异步操作,组件渲染时数据可能还未返回,此时遍历未就绪的数组会导致属性访问失败
修复方案
方案1:添加数据存在性判断
在渲染标记点前,先检查points是否有数据,确保points[0]和points[0].cameras存在后再遍历。
方案2:使用可选链操作符(ES2020+)
通过?.操作符自动处理undefined的情况,避免报错。
同时需要给Marker组件添加唯一key属性,符合React列表渲染规范。
修改后的完整代码示例
function App() { const [points, setPoints] = useState([]); useEffect(() => { fetch('/cameras-by-date') .then(res => res.json()) .then(data => { setPoints(data); }) .catch(err => console.error('数据请求失败:', err)); // 添加错误捕获,避免请求异常导致状态异常 }, []); const offline = [ { "cameras": [ { "location": "ANZAC HWY, ASHFORD", "position": { "lat": -34.9502955, "lng": 138.575806 } } ], "date": "03/09/2022" } ] const { isLoaded } = useJsApiLoader({ id: 'google-map-script', googleMapsApiKey: MAPS_API_KEY }) const [map, setMap] = React.useState(null) const onLoad = React.useCallback(function callback(map) { const bounds = new window.google.maps.LatLngBounds(center); map.fitBounds(bounds); setMap(map) }, []) if (!isLoaded) { return <div>地图加载中...</div>; // 添加加载提示,提升用户体验 } return ( <div className="App"> <header className="App-header"> <GoogleMap mapContainerStyle={containerStyle} center={center} zoom={10} options={options} onLoad={map => setMap(map)} > {/* 方案1:判断数据存在后再遍历(二选一即可) */} {points.length > 0 && points[0].cameras.length > 0 && points[0].cameras.map(({ position }, index) => ( <Marker key={index} position={position} /> )) } {/* 方案2:使用可选链 */} {/* {points[0]?.cameras?.map(({ position }, index) => ( <Marker key={index} position={position} /> ))} */} </GoogleMap> </header> </div > ); } export default App;
额外注意事项
- 确保接口返回的数据结构与
offline完全一致,每个元素都包含cameras数组 - 列表渲染的
key优先使用数据中的唯一标识(如相机ID)而非索引,提升渲染性能 - 地图未加载完成时添加提示,避免空白页面影响体验
内容的提问来源于stack exchange,提问作者FIREWORKKS
相关产品推荐
相关产品推荐

