React Hook:重新渲染列表项导致无限循环
React Hook: rerender list item cause infinite loop
我创建了一个用户列表(运行良好),对于某些用户,我需要调用新的异步函数(获取)来更新数据。但这会导致无限循环。
这是我的代码:
function UserTableRow(props) {
const [pointOfSales, updatePointOfSales] = useState([])
function Pos({ id }) {
useEffect(() => {
let mounted = true
pointOfSaleService.getById(id).then((pointOfSale: PointOfSale) => {
if (mounted && !pointOfSales.includes(pointOfSale)) {
updatePointOfSales([...pointOfSales, pointOfSale]) <---- loop here
}
})
return function cleanup() {
mounted = false
}
}, [])
if (pos) {
return <Typography variant="body2">{pointOfSales[pointOfSales.length-1].name}</Typography>
} else {
return <span />
}
}
return (
<TableRow>
<UserTableCell component="th" scope="row">
{user.name}
</UserTableCell>
...
<UserTableCell align="left">
{user.posId > 0 && <Pos id={user.posId} />}
</UserTableCell>
</TableRow>
)
}
我测试了什么:
- 如果我将 pos 或 pointOfSales 作为 useEffect 的依赖项,我得到相同的结果
- 同上,如果我不使用 useEffet,直接 pointOfSaleService.getById(id)
有两个主要问题我不明白。
- 数组填的很好,但是为什么这行!pointOfSales.includes(pointOfSale)行不通?
- 尽管方法 pointOfSaleService.getById(id) 总是检索相同的销售点,但为什么销售点会更新为“updatePointOfSales”?
请帮帮我
尝试简化您的代码。在我看来,Pos
是一个展示组件,它不应该执行任何请求(应该在 UserTableRow
中完成)。
function UserTableRow({ user }) {
const [pointOfSales, updatePointOfSales] = useState([])
useEffect(() => {
let mounted = true
pointOfSaleService.getById(user.posId).then(pointOfSale => {
// I assume pointOfSale is a string
// if it does, consider changing pointOfSales to string instead of Array
if (mounted && !pointOfSales.includes(pointOfSale)) {
updatePointOfSales([...pointOfSales, pointOfSale])
}
})
return function cleanup() {
mounted = false
}
}, [user.posId])
return (
<TableRow>
<UserTableCell component="th" scope="row">
{user.name}
</UserTableCell>
...
<UserTableCell align="left">
{
pointOfSales.length > 0
? <Typography variant="body2">{pointOfSales[pointOfSales.length-1].name}</Typography>
: <span/>
}
</UserTableCell>
</TableRow>
)
}
关于您实施的方法的最后一件事是它的性能非常糟糕。图像有 50 个用户,当您呈现他们相应的行时,您将向您的服务器发出 50 个请求(我宁愿在检索用户时包括 pointOfSale)。
我创建了一个用户列表(运行良好),对于某些用户,我需要调用新的异步函数(获取)来更新数据。但这会导致无限循环。
这是我的代码:
function UserTableRow(props) {
const [pointOfSales, updatePointOfSales] = useState([])
function Pos({ id }) {
useEffect(() => {
let mounted = true
pointOfSaleService.getById(id).then((pointOfSale: PointOfSale) => {
if (mounted && !pointOfSales.includes(pointOfSale)) {
updatePointOfSales([...pointOfSales, pointOfSale]) <---- loop here
}
})
return function cleanup() {
mounted = false
}
}, [])
if (pos) {
return <Typography variant="body2">{pointOfSales[pointOfSales.length-1].name}</Typography>
} else {
return <span />
}
}
return (
<TableRow>
<UserTableCell component="th" scope="row">
{user.name}
</UserTableCell>
...
<UserTableCell align="left">
{user.posId > 0 && <Pos id={user.posId} />}
</UserTableCell>
</TableRow>
)
}
我测试了什么:
- 如果我将 pos 或 pointOfSales 作为 useEffect 的依赖项,我得到相同的结果
- 同上,如果我不使用 useEffet,直接 pointOfSaleService.getById(id)
有两个主要问题我不明白。
- 数组填的很好,但是为什么这行!pointOfSales.includes(pointOfSale)行不通?
- 尽管方法 pointOfSaleService.getById(id) 总是检索相同的销售点,但为什么销售点会更新为“updatePointOfSales”?
请帮帮我
尝试简化您的代码。在我看来,Pos
是一个展示组件,它不应该执行任何请求(应该在 UserTableRow
中完成)。
function UserTableRow({ user }) {
const [pointOfSales, updatePointOfSales] = useState([])
useEffect(() => {
let mounted = true
pointOfSaleService.getById(user.posId).then(pointOfSale => {
// I assume pointOfSale is a string
// if it does, consider changing pointOfSales to string instead of Array
if (mounted && !pointOfSales.includes(pointOfSale)) {
updatePointOfSales([...pointOfSales, pointOfSale])
}
})
return function cleanup() {
mounted = false
}
}, [user.posId])
return (
<TableRow>
<UserTableCell component="th" scope="row">
{user.name}
</UserTableCell>
...
<UserTableCell align="left">
{
pointOfSales.length > 0
? <Typography variant="body2">{pointOfSales[pointOfSales.length-1].name}</Typography>
: <span/>
}
</UserTableCell>
</TableRow>
)
}
关于您实施的方法的最后一件事是它的性能非常糟糕。图像有 50 个用户,当您呈现他们相应的行时,您将向您的服务器发出 50 个请求(我宁愿在检索用户时包括 pointOfSale)。