TypeError:无法读取未定义的 React js 的属性
2023-01-21
5178
我试图从每个页面输出一个数组中的数据。
此代码抛出错误 Uncaught TypeError: Cannot read properties of undefined (reading 'word')
虽然
array newArr
和数据
newArr[i].word
都输出到控制台。
const shuffle = (arr) => arr.sort(() => Math.random() - 0.5);
function Home({ data, num }) {
const [newArr, setNewArr] = useState([]);
const [i, setI] = useState(0);
useEffect(() => {
setNewArr(shuffle(data));
}, []);
const randomCard = () => {
if (i < newArr.length - 1) {
setI(i + 1);
console.log(i);
console.log(newArr);
console.log(newArr[i].word);
} else {
setNewArr(shuffle(data));
setI(0);
}
};
return (
<div>
<div className="home-inner">
{num >= 1 ? (
<div className="home-stat">
<div onClick={() => randomCard} className="home-random">
<div className="hr-card">
<p className="randomword">{newArr[i].word}</p>
<p className="randomtranslate">{newArr[i].translate}</p>
</div>
</div>
</div>
) : (
<div>
{" "}
<Link className="main-btn" to="/addcard">
Add
</Link>
</div>
)}
</div>
</div>
);
}
export default Home;
1个回答
您的错误发生在组件的第一次渲染时。发生这种情况的原因是
i
为
0
且
newArr
为
[]
,这是一个空数组,当您尝试渲染它时 - newArr[0] - 它返回
undefined
。
要解决此问题 - 使用实际值初始化
newArr
并在渲染位置添加额外检查。
function Home({ data, num }) {
// Initialize newArr with initial data instead of useEffect
const [newArr, setNewArr] = useState(shuffle([...data]));
const [i, setI] = useState(0);
// just a utility
const randomCard = useMemo(() => {
// you can add some console.logs here for debugging purposes, just in case
if (!newArr || i < 0 || i >= newArr.length) return undefined;
return newArr[i];
}, [newArr, i]);
// changed naming here
const randomizeCard = () => {
if (i < newArr.length - 1) {
setI(i + 1);
} else {
setNewArr(shuffle([...data]));
setI(0);
}
};
return (
<div>
<div className="home-inner">
{/* Added additinal check */}
{num >= 1 && randomCard ? (
<div className="home-stat">
{/* fixed onClick binding */}
<div onClick={randomizeCard} className="home-random">
<div className="hr-card">
<p className="randomword">{randomCard.word}</p>
<p className="randomtranslate">{randomCard.translate}</p>
</div>
</div>
</div>
) : (
<div>
{" "}
<Link className="main-btn" to="/addcard">
Add
</Link>
</div>
)}
</div>
</div>
);
}
注意:sort() 方法对数组元素进行就地排序并返回对同一数组的引用,因此您正在改变
data
参数,这通常不应该发生,同时如果您使用相同的“值”设置状态,React 将不会检测到更改,这意味着 Array 对象始终具有相同的引用。这里有一些详细信息:
将数组设置为等于另一个数组或使用三个点之间的区别
。 解决方案是
shuffle([...data])
,它将创建
data
的浅表副本。
注意 2:在调用
setI(i + 1);
和
console.log(i);
之后立即调用 - 不会按您预期的方式工作,因为
状态值将仅在下一次渲染时更新
Sergey Sosunov
2023-01-21