未捕获的类型错误:无法在我的 React 应用程序中读取未定义的属性(读取“长度”)
2022-05-18
1496
我正在开发一个 React 应用,但遇到了未捕获的类型错误。我按照在线教程操作,但无法修复。这是我的代码:
import React, { useState, useEffect, createRef } from 'react';
import { CircularProgress, Grid, Typography, InputLabel, MenuItem, FormControl, Select } from '@material-ui/core';
import PlaceDetails from '../PlaceDetails/PlaceDetails';
import useStyles from './styles.js';
const List = ({ places, type, setType, rating, setRating, childClicked, isLoading }) => {
const [elRefs, setElRefs] = useState([]);
const classes = useStyles();
useEffect(() => {
setElRefs((refs) => Array(places.length).fill().map((_, i) => refs[i] || createRef()));
}, [places]);
return (
<div className={classes.container}>
<Typography variant="h4">Food & Dining around you</Typography>
{isLoading ? (
<div className={classes.loading}>
<CircularProgress size="5rem" />
</div>
) : (
<>
<FormControl className={classes.formControl}>
<InputLabel id="type">Type</InputLabel>
<Select id="type" value={type} onChange={(e) => setType(e.target.value)}>
<MenuItem value="restaurants">Restaurants</MenuItem>
<MenuItem value="hotels">Hotels</MenuItem>
<MenuItem value="attractions">Attractions</MenuItem>
</Select>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel id="rating">Rating</InputLabel>
<Select id="rating" value={rating} onChange={(e) => setRating(e.target.value)}>
<MenuItem value="">All</MenuItem>
<MenuItem value="3">Above 3.0</MenuItem>
<MenuItem value="4">Above 4.0</MenuItem>
<MenuItem value="4.5">Above 4.5</MenuItem>
</Select>
</FormControl>
<Grid container spacing={3} className={classes.list}>
{places?.map((place, i) => (
<Grid ref={elRefs[i]} key={i} item xs={12}>
<PlaceDetails selected={Number(childClicked) === i} refProp={elRefs[i]} place={place} />
</Grid>
))}
</Grid>
</>
)}
</div>
);
};
export default List;
在使用在线教程中的 circularProgress 之前,我为我的位置创建了一个引用,他遇到了和我一样的错误,但当他使用 circularProgress 时,他能够修复它,但我不明白为什么我的错误无法修复
1个回答
看起来
places
属性是动态的,有时未定义。您可以提供一些后备值。在
places.length
访问上使用可选链接运算符,如果
places
为 null 或未定义,则提供
0
作为后备值。
useEffect(() => {
setElRefs((refs) => Array(places?.length ?? 0)
.fill()
.map((_, i) => refs[i] || createRef())
);
}, [places]);
您还可以提供默认的
places
属性值。
const List = ({
places = [],
type,
setType,
rating,
setRating,
childClicked,
isLoading,
}) => {
...
更常见的模式是使用 React ref 来存储 refs 数组,而不是使用本地状态。示例:
const elRefs = React.useRef([]);
elRefs.current = Array(places?.length ?? 0)
.fill()
.map((_, i) => elRefs.current[i] || createRef());
...
{places?.map((place, i) => (
<Grid ref={elRefs[i]} key={i} item xs={12}>
<PlaceDetails
selected={Number(childClicked) === i}
refProp={elRefs.current[i]}
place={place}
/>
</Grid>
))}
这提供了更稳定的 ref 引用,因为在
places
属性更新时不会创建所有新的 refs。
Drew Reese
2022-05-18