Reactjs 钩子 useState 奇怪的行为

时间:2021-05-11 09:04:55

标签: javascript reactjs react-hooks use-state

我正在尝试显示从 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 的结果,使用另一个来更新组件列表。但是当我显示 Content 时,它总是从列表中丢失一个或多个项目,即使列表只有 2 个元素。当我显示 tmp 时,它包含所有组件以及当我显示组件列表时。不知道为什么,但是好像setComponents的更新不影响返回。

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

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

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

错误是因为 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)
        })
      }
      
    })

  })

答案 2 :(得分:-1)

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