嵌套异步函数中的setState-React Hooks

问题描述 投票:1回答:2

如何构建一个异步获取一些数据然后使用该数据获取更多异步数据的函数?

我正在使用Dexie.js(indexedDB包装器)来存储有关直接消息的数据。我存储在对象中的一件事是我将向其发送消息的用户ID。为了构建更好的UI,我还获得了有关该用户的一些信息,例如配置文件图片,用户名和显示名称,这些信息存储在远程rdbms中。要在两个数据库(本地indexedDB和远程rdbms)中的需要数据中构建完整的链接组件。

我的解决方案返回一个空数组。当它在Google Chrome浏览器中记录时正在计算,我确实看到了我的数据。但是,由于未在渲染时进行计算,因此数组始终为空,因此我无法对其进行迭代以构建组件。

const [conversations, setConversations] = useState<IConversation[]>()
const [receivers, setReceivers] = useState<Profile[]>()
useEffect(() => {
    messagesDatabase.conversations.toArray().then(result => {
      setConversations(result)
    })
  }, [])

  useEffect(() => {
    if (conversations) {
      const getReceivers = async () => {
        let receivers: Profile[] = []
        await conversations.forEach(async (element) => {
          const receiver = await getProfileById(element.conversationWith, token)
          // the above await is a javascript fetch call to my backend that returns json about the user values I mentioned
          receivers.push(receiver)
        })
        return receivers
      }
      getReceivers().then(receivers => {
        setReceivers(receivers)
      })
    }
  }, [conversations])
  /*
    The below log logs an array with a length of 0; receivers.length -> 0
    but when clicking the log in Chrome I see:
    [
     0: {
       avatarURL: "https://lh3.googleusercontent.com/..."
       displayName: "Cool guy"
       userId: "1234"
       username: "cool_guy"
     }
     1: ...
    ]

  */
  console.log(receivers) 

我的计划是然后使用map遍历此数组

{
  receivers && conversations
  ? receivers.map((element, index) => {
    return  <ChatLink 
              path={conversations[index].path}
              lastMessage={conversations[index].last_message}
              displayName={element.displayName}
              username={element.username}
              avatarURL={element.avatarURL}
              key={index}
            />
    })
  : null
}

如何编写此代码以不返回空数组?这是一个与我正在经历的问题有关的here

javascript reactjs indexeddb
2个回答
0
投票

我认为它正在发生,因为对于getReceivers()函数是异步的。它等待响应,与此同时,您的状态呈现为空数组。

您可以显示微调框,直到收到响应。像

const[isLoading,setLoading]= useState(true)
    useEffect(()=>{
         getReceivers().then(()=>{setLoading(false)}).catch(..)
        } )
  return  {isLoading ? <spinner/> : <yourdata/>}

0
投票

请将接收者的初始值设置为数组

const [receivers, setReceivers] = useState<Profile[]>([])

我不确定这是您问题的解决方案但它可以帮助您解决错误]

© www.soinside.com 2019 - 2024. All rights reserved.