我有一个列表,我希望每次 ajax 请求获取一页数据后,将新的一页数据追加到列表当中。
在组件挂载时,我希望读取第一页的内容。简化后的代码可以写成这样:
import {useEffect, useState} from "react";
interface User {
id: number
name: string
}
const pageData = [
{id: 1, name: '张三'},
]
export default function App() {
const [users, setUsers] = useState<User[]>([])
const fetchUsers = async () => {
const page = pageData // 异步获取到数据
setUsers([...users, ...page])
}
useEffect(() => {
fetchUsers() // 发送异步请求
}, [])
// 渲染列表
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
这样不会有任何问题。
但是今天我问 ChatGPT 的时候,他给了我这么个回答。
我觉得有点道理。所以我就在想,我是往列表里追加数据,那肯定是依赖于前一个状态的。因此我就把代码从
setUsers([...users, ...page])
改成了
setUsers(prevUsers=>[...prevUsers, ...page])
完整代码 :
import {useEffect, useState} from "react";
interface User {
id: number
name: string
}
const pageData = [
{id: 1, name: '张三'},
]
export default function App() {
const [users, setUsers] = useState<User[]>([])
const fetchUsers = async () => {
const page = pageData // 异步获取到数据
setUsers(prevUsers=>[...prevUsers, ...page])
}
useEffect(() => {
fetchUsers() // 发送异步请求
}, [])
// 渲染列表
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
但这时候就出现了报错:
列表的数据追加了两次,key 也重复了。
我立马想到 React 的严格模式,果然关闭了,就又正常了:
到目前为止,我确实可以简单地
以解决这个问题。
但是我觉得使用函数式的 setState 其实并没有太大问题,而 React 的严格模式又是官方推荐的。这俩者结合到一起,咋就出问题了呢?望大佬指点,是不是我使用的方式有问题。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.