【问题标题】:Reactjs hook useState weird behaviourReactjs hook useState 奇怪的行为
【发布时间】:2021-08-01 15:21:13
【问题描述】:

我正在尝试显示从 API 调用到组件列表的 Item 列表。

这是我的代码:

function Content({...props}) {
  const [list, setList] = useState([])
  const [loading, setLoading] = useState(true)
  const [components, setComponents] = useState([])

  useEffect(() => {
    if (!loading) {
      return;
    }
    API.getInfo((data) => {
      setLoading(false)
      setComponents([])
      setList(data)
      console.log(data)
    })

  })

  useEffect(() => {
    if (components.length > 0) {
      return;
    }
    let tmp = [...components];
    for (const elem in list)  {
      const info = list[elem]
      API.getUserById(info.userid, (data) => {
        tmp.push(<InfoItem id={info._id} key={info._id} info={info} module={info.module} since="N/A" user={data.initial ? data.initial : `${data.firstname} ${data.lastname}`} {...props}/>)
        setComponents(tmp)
        console.log(tmp)
      })
    }
  }, [list])

    console.log(components)

    return(
        <div className="container-fluid">
            <div className="row">
                <CardHeader title="My tittle"/>
                <div className ="col-lg-12">
                    {loading ?
                      <Card content={"Loading..."}/>
                    :
                      <Card content={
                        <div style={{height: "62vh", overflow: "hidden"}}>
                            <div className="list-group h-100" style={{overflowY: "scroll"}}>
                              {components ? components : <p>Nothing</p>}
                            </div>
                        </div>
                    }/>
                    }
                </div>
            </div>
        </div>
    )
}

如您所见,我使用一个 useEffect 来处理来自 API 的结果,另一个用于更新组件列表。但是当我显示内容时,它总是从列表中丢失一个或多个项目,即使列表只有 2 个元素。当我显示 tmp 时,它包含所有组件以及当我显示组件列表时。不知道为什么,好像setComponents的更新不影响返回。

如果我尝试添加一些假元素并快速重新加载,所有组件都在弹出,我不知道如何强制更新列表组件。

如果有人知道缺失的元素是从哪里来的,那就太好了。谢谢。

【问题讨论】:

  • 你的循环中有这个,setComponents(tmp)。这只会更新单个项目到达时间的组件,您需要将循环内的所有项目推送到一个数组中,然后对其调用 setState。
  • 我想说在这里使用两个 useEffect 回调是一件很奇怪的事情,你的渲染需要组件,所以只需在一个 useEffect 中完成所有事情,否则你会无缘无故地进行额外的渲染。
  • @Keith 我同意你的第一条评论,但我不知道如何在使用 setComponents 之前等待 tmp 中的所有组件

标签: javascript reactjs react-hooks use-state


【解决方案1】:

我认为您需要等待异步任务完成。尝试在API.getUserById 中加入await.then。在执行setComponents(tmp) 时,您的数据可能尚未检索到。

【讨论】:

  • 感谢您的帮助,但API.getUserById 中的匿名函数(data) =&gt; {...} 是请求后then 中的回调调用,因此数据在被推送到tmp 之前可以很好地检索跨度>
【解决方案2】:

错误是因为 tmp 数组保持不变,即使在推送新项目时 setComponents 也不会呈现,因为它仍然是同一个数组,这是我为解决该问题所做的:

useEffect(() => {
    if (!loading) {
      return;
    }
    API.getInfo((data) => {
      setLoading(false)
      let all = []
      for (const elem in data)  {
        const info = data[elem]
        API.getUserById(info.patientid, (data) => {
          let tmp = [...all]
          tmp.push(<InfoItem id={info._id} key={info._id} info={info} module={info.module} since="N/A" patient={data.initial ? data.initial : `${data.firstname} ${data.lastname}`} {...props}/>)
          all.push(tmp[tmp.length - 1])
          setComponents(tmp)
          console.log(tmp)
        })
      }
      
    })

  })

【讨论】:

    【解决方案3】:
    useEffect(() => {
        if (!loading) {
          return;
        }
        API.getInfo((data) => {
          setLoading(false)
          setComponents([])
          setList(data)
          console.log(data)
        })
      },[]);
    

    【讨论】:

      猜你喜欢
      • 2021-08-17
      • 2022-11-15
      • 2021-03-02
      • 2022-01-18
      • 1970-01-01
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      • 2021-04-14
      相关资源
      最近更新 更多