简体   繁体   English

Reactjs hook useState 奇怪的行为

[英]Reactjs hook useState weird behaviour

I'm trying to display a list of Item from an API call to a list of components.我正在尝试显示从 API 调用到组件列表的项目列表。

Here's my code:这是我的代码:

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>
    )
}

As you can see I use one useEffect to handle the result from the API and another one to update the components list.如您所见,我使用一个 useEffect 来处理来自 API 的结果,另一个用于更新组件列表。 But when I display Content, it's always missing one or many item from the list, even when the list have only 2 elements.但是当我显示内容时,它总是从列表中丢失一个或多个项目,即使列表只有 2 个元素。 And when I display tmp, it's contain all the components as well as when I display the components list.当我显示 tmp 时,它包含所有组件以及当我显示组件列表时。 I don't know why but it seems that the update of setComponents doesn't affect the return.我不知道为什么,但似乎 setComponents 的更新并不影响返回。

If I try to add some fake elements and fast reload, all the component are poping, I don't know how to force update the list component.如果我尝试添加一些假元素并快速重新加载,所有组件都会弹出,我不知道如何强制更新列表组件。

If someone know where that missing elements can came from it will be great.如果有人知道缺失的元素是从哪里来的,那就太好了。 thank you.谢谢你。

I think you need to wait for the async task to finish.我认为您需要等待异步任务完成。 Try to fit an await or a .then in the API.getUserById .尝试在API.getUserById中加入await.then Your data probably has not yet been retrieved by the time the setComponents(tmp) is executed.到执行setComponents(tmp)时,您的数据可能还没有被检索到。

The error is because the tmp array stay the same, even when new item are push so the setComponents doesn't render because it's still the same array, here's what I've done to fix that:错误是因为 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)
        })
      }
      
    })

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM