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 是一个展示组件,它不应该执行任何请求(应该在 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)。