仅在第二次渲染时设置状态(react-native)

State only set on second render (react-native)

我正在从 Realm 文件数据库中提取数据,但数据似乎只出现在第二次渲染中。这是我的代码:

import React, { useState, useEffect } from 'react'
import {getAllArchive} from '../Schemas/activitiesArchiveSchema';

const Stats = () => {
  const [Archives, setArchives] = useState();

  useEffect(() => {
    (async () => setArchives(await getAllArchive()))();
    console.log(JSON.stringify(Archives))
  }, []);

数据库函数:

export const getAllArchive = () => {
    return new Promise((resolve, reject) => {
        Realm.open(databaseOptions).then(realm => {
            let activitiesList = realm.objects(ARCHIVE_LIST_SCHEMA)
            resolve(activitiesList)
        }).catch((error) => reject(error))
    })
}

输出:

 LOG  undefined
 LOG  {"0":{"title":"sw2","records":{"0":{"date":"4/28/2021","seconds":7,"minutes":0,"hours":1},"1":{"date":"4/27/2021","seconds":7,"minutes":0,"hours":0},"2":{"date":"4/28/2021","seconds":7,"minutes":0,"hours":0}}},"1":{"title":"jj","records":{"0":{"date":"4/25/2021","seconds":0,"minutes":55,"hours":1}}},"2":{"title":"l,kl","records":{"0":{"date":"4/28/2021","seconds":4,"minutes":12,"hours":1}}},"3":{"title":"fsdfdsf","records":{"0":{"date":"4/25/2021","seconds":4,"minutes":43,"hours":1}}},"4":{"title":"sideProj","records":{"0":{"date":"4/26/2021","seconds":30,"minutes":29,"hours":1},"1":{"date":"4/27/2021","seconds":15,"minutes":18,"hours":1}}},"5":{"title":"work","records":{"0":{"date":"4/28/2021","seconds":36,"minutes":13,"hours":0},"1":{"date":"4/28/2021","seconds":37,"minutes":11,"hours":3}}},"6":{"title":"plp","records":{"0":{"date":"4/25/2021","seconds":2,"minutes":12,"hours":3}}},"7":{"title":"fff","records":{"0":{"date":"4/25/2021","seconds":3,"minutes":10,"hours":2}}},"8":{"title":"Work","records":{"0":{"date":"4/27/2021","seconds":1,"minutes":0,"hours":0}}},"9":{"title":"chilling","records":{"0":{"date":"4/27/2021","seconds":40,"minutes":4,"hours":3},"1":{"date":"4/27/2021","seconds":0,"minutes":0,"hours":0}}}}

有人能指出代码中的任何问题吗?谢谢

不就是你的console.log发生在setArchives之前吗?尝试强制您的日志等待异步 return 对其进行测试。

我很确定你不能在这里异步设置状态:

(async () => setArchives(await getAllArchive()))(); setState 不是异步 api,是吗? 尝试:

useEffect(() => {
  (async () => {
    const data = await getAllArchive();// async fetch data and store it in variable

    console.log(JSON.stringify(data, null, 2)); //log your response

    if(data){

      setArchives(data) //if success, then set state

    }else{
      console.log('could not fetch data') //if fail, resolve error somehow
    }
  }
  )();
  
}, []);

我是 React 新手,所以我希望我的代码在第一次渲染时等待并更新状态。然而,它预计在第一次渲染时没有价值,处理它的方法基本上是 运行 另一个 useEffect 挂钩中的依赖代码,该挂钩在其依赖项数组中具有该状态。这是代码:

import React, { useState, useEffect } from 'react'
import {getAllArchive} from '../Schemas/activitiesArchiveSchema';

const Stats = () => {
  const [Archives, setArchives] = useState();

  useEffect(() => {
    (async () => setArchives(await getAllArchive()))();
  }, []);

  useEffect(() => {
    // "dependent code"
    console.log(JSON.stringify(Archives))
  }, [Archives])

显然第一个渲染未定义,但第二个渲染应该有值更改。

谢谢

您的数据未在组件的第一次渲染中加载,这不足为奇。 首先,让我们看看如果您不提供任何依赖项,useEffect 会做什么 - 它会在每次重新渲染时执行。

在这行代码中:

(async () => setArchives(await getAllArchive()))();

您正在获取异步数据,执行不会在此处暂停。所以,console.log(JSON.stringify(Archives)) 将被执行。如果 Archived 仍然是 undefined(意味着数据获取不完整),您会看到 LOG undefined。当异步数据获取完成并更新状态时,导致组件重新渲染的原因是 useEffect 再次被调用,您会看到

LOG  {"0":{"title":"sw2","records":{"0":{"date":"4/28/2021","seconds":7,"minutes":0,"hours":1},"1":{"date":"4/27/2021","seconds":7,"minutes":0,"hours":0},"2":{"date":"4/28/2021","seconds":7,"minutes":0,"hours":0}}},"1":{"title":"jj","records":{"0":{"date":"4/25/2021","seconds":0,"minutes":55,"hours":1}}},"2":{"title":"l,kl","records":{"0":{"date":"4/28/2021","seconds":4,"minutes":12,"hours":1}}},"3":{"title":"fsdfdsf","records":{"0":{"date":"4/25/2021","seconds":4,"minutes":43,"hours":1}}},"4":{"title":"sideProj","records":{"0":{"date":"4/26/2021","seconds":30,"minutes":29,"hours":1},"1":{"date":"4/27/2021","seconds":15,"minutes":18,"hours":1}}},"5":{"title":"work","records":{"0":{"date":"4/28/2021","seconds":36,"minutes":13,"hours":0},"1":{"date":"4/28/2021","seconds":37,"minutes":11,"hours":3}}},"6":{"title":"plp","records":{"0":{"date":"4/25/2021","seconds":2,"minutes":12,"hours":3}}},"7":{"title":"fff","records":{"0":{"date":"4/25/2021","seconds":3,"minutes":10,"hours":2}}},"8":{"title":"Work","records":{"0":{"date":"4/27/2021","seconds":1,"minutes":0,"hours":0}}},"9":{"title":"chilling","records":{"0":{"date":"4/27/2021","seconds":40,"minutes":4,"hours":3},"1":{"date":"4/27/2021","seconds":0,"minutes":0,"hours":0}}}}