为什么我的组件在更新上下文时不重新渲染?



我想在从API获取数据后呈现一个表,我使用Context API和自定义挂钩来更新上下文。我知道我的钩子正在工作,因为第二个useEffect记录了数据。我知道React中的状态更新是异步的,但我认为上下文的更改会触发重新发布。

import React, { useEffect, useContext } from "react";
import { titleCase } from "title-case";
import dataContext from "../../context/dataContext";
const fetchUsers = async (url:string) => {
const response = await fetch(url);
return response.json();
};

const Table = () => {
const {data, setData } = useContext(dataContext);
useEffect(() => {
fetchUsers(`https://randomuser.me/api/?results=50`).then(
(res) => {setData([...data, res.results]) ;
}
)

}, [])
useEffect(() => {
console.log(data)
}, [data])

return (
<table>
<thead>
<tr>
<th>
Name
</th>
<th>
Gender
</th>
<th>
Birth
</th>
<th>
Actions
</th>
</tr>
</thead>
<tbody>
{data.length >0 && data.map((user: Record<string, any>, index: number) => {
const dob = new Date(user.dob.date);
return (
<tr>
<td>
{`${titleCase(user.name.first)} ${titleCase(user.name.last)}`}
</td>
<td>
{titleCase(user.gender)}
</td>
<td>
{dob.toLocaleDateString()}
</td>
<td>
<button>View</button>
</td>
</tr>
);
})}

</tbody>
</table>
);
};
export default Table;

您发布的代码存在多个问题。

  1. 您需要在setData中分解res.results的结构。如果不这样做,用户数组将存储为单个对象,而不是存储所有多个用户对象。setData([...data, ...res.results)
  2. 您应该为列表中的每个子项提供一个唯一的密钥。点击此处了解更多信息。您可以使用每个用户的login.uuid字段作为密钥。<tr key={user.login.uuid}>
  3. 您需要提供data作为useEffect挂钩的依赖项
  4. 最后,如果您使用一个设置的间隔对随机用户API进行调用,如果useEffect钩子不连续执行,那就更好了

我做了一个简单的演示,它遵循了以上几点。在演示中,我没有使用上下文。我每10秒就会吸引2个新用户,然后用他们的电子邮件更新一个表格。演示链接。

我知道这是一篇迟发的帖子,但我花了一些时间研究这篇文章,并认为这可能会对你有所帮助。希望你现在已经解决了你的问题。

最新更新