reactjs - React Hooks,setState 的更新值显示另一个组件中的初始值

标签 reactjs

刚刚开始探索 React Hooks。我想创建一个 API 获取组件,将其导入另一个组件 - 以便我可以在其他组件中重用该 API 获取组件。

发生的事情是我设置了初始状态值:

API.js

import { useState, useEffect } from "react";

export const useUserFetch = () => {

  const [users, setUsers] = useState({
    loading: true,
    error: false,
    data: [],
  });

然后在 useEffect 中执行异步获取:

useEffect(() => {
    async function fetchUserQuery() {
      await fetch('http://jsonplaceholder.typicode.com/users')
        .then(response => {
          console.log('API RESPONSE: ', response)
          if (response.status === 200 && response.status < 400) {
            response.json().then((respData) => {
              setUsers({ loading: false, error: false, data: respData })
            })
          } else {
            response.json().then(err => {
              setUsers({ loading: false, error: err, data: [] })
            })
          }
        }).catch(err => {
          setUsers({ loading: false, error: err, data: [] })
        })
    }
    fetchUserQuery()
  }, [])

如果响应状态为 200(左右),则更改我的状态数组以包含响应的更新值。错误处理也一样。获取完成后,我检查并返回加载、错误和数据的值(以及控制台记录这些值):

if (users.loading) {
    console.log('API LOADING: ', users.loading)
    return "Loading..."
  }

  if (users.error) {
    console.log('API ERROR: ', users.error)
    return "Error..."
  }

  if (users.data) {
    console.log('API DATA: ', users.data)
    return users;
  }

如您所见,最后检查的是数据,如果有数据,则控制台记录 API DATA 并返回数据。问题是,在返回数据之前,控制台输出数据显示用户数组(它有效,请参阅下面的包含控制台日志)。但是,当我将 Api.js 导入 Contacts.js 并尝试输出数据时,它仍然显示用户状态的初始值。

Contacts.js:

import { useEffect, useState } from 'react'

import { useUserFetch } from '../Api';

const Users = () => {
    const [userData, setUserData] = useState(useUserFetch());
    console.log('CONTACT STATE: ', userData)

    useEffect(() => {
        async function fetchUserState() {
            const userJsonData = await userData
            setUserData(userJsonData)
        }
        fetchUserState()
    }, [])

    if (userData.loading) return "Loading...";
    if (userData.error) return userData.error.message
    if (userData.data) return JSON.stringify(userData.data)

    return true
};

export default Users

以下是控制台显示的内容(按确切顺序):

API LOADING: true

Contacts.js:7 CONTACT STATE: Loading...

Api.js:14 API RESPONSE: Response {type: "cors", url: "http://jsonplaceholder.typicode.com/users", redirected: false, status: 200, ok: true, …}

Api.js:42 API DATA: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

Contacts.js:7 CONTACT STATE: Loading...

所以我的第一个问题;这是 setState 异步的问题吗?如果是这样,我该如何处理这个问题以确保当我返回用户状态时,我的 Contacts.js 获得更新的值。或者它是任一文件中我的 useEffect 中的异步?或者是其他东西?我只是想了解一下新的 Hooks,并在将来探索 Redux/MobX 或 Context API。

最佳答案

根据docs ,

How does a custom Hook get isolated state? Each call to a Hook gets isolated state. Because we call [custome hook](modified word, in docs it is a hook name from example) directly, from React’s point of view our component just calls useState and useEffect.

正如我们所知,我们可以在一个组件中多次调用 useState 和 useEffect,并且它们将完全独立。

由于状态是隔离的,因此您必须对自定义 Hook 有一个单独的引用,将其作为第二个参数传递给 useEffect ,以便正确获取状态,

const App = () => {
    const [userData, setUserData] = useState(useUserFetch());
    let users = useUserFetch(); //Get seperate reference

    console.log('CONTACT STATE: ', userData)

    useEffect(() => {
        async function fetchUserState() {
            const userJsonData = await users //get data
            setUserData(userJsonData)
        }
        fetchUserState()
    },[users]) //Pass as dependency

    if (userData.loading) return "Loading...";
    if (userData.error) return userData.error.message
    if (userData.data) return JSON.stringify(userData.data)

    return true
};

关于reactjs - React Hooks,setState 的更新值显示另一个组件中的初始值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57129934/

相关文章:

reactjs - 你能给 React 中的 <> 空元素添加属性吗?

javascript - 无法在客户端填充缩略图

audio - 更改音频元素的src属性不起作用

reactjs - React .- JSX 中的 reduce() 未渲染

javascript - 使用 useEffect 将 react 查询状态移动到 useState

javascript - 在 Redux reducer 中对对象数组进行排序

javascript - 如何测试元素(标签)是否用 jest/enzyme 渲染?

javascript - Assets 在 GatsbyJS 项目(Netlify 托管)中加载速度非常慢

javascript - 使用 Redux 让 React 组件执行一次性操作?

reactjs - 在 React 组件中保留与 ui 相关的强状态是一种不好的做法吗?