【问题标题】:asynchronous context with useEffect in ReactReact 中带有 useEffect 的异步上下文
【发布时间】:2020-05-29 06:28:50
【问题描述】:

我正在尝试使用从上下文组件接收的标头值创建一个 api 请求。然而,一旦页面组件被加载,它就会抛出一个Cannot read property '_id' of null 异常。有没有办法在加载上下文后立即运行 useEffect 函数?

主要组件:

import React, { useState, useEffect, useContext } from "react";
import "./overview.scss";

/* COMPONENTS */;
import axios from 'axios';
import { GlobalContext } from '../../components/context/global';

const Overview = () => {
  const [bookings, setBookings] = useState([]);
  const [loaded, setLoaded] = useState(false);

  const [user, setUser] = useContext(GlobalContext);

  useEffect(() => {
      axios
      .get(`/api/v1/bookings/user/${user._id}`)
      .then(res => setBookings(res.data))
      .catch(err => console.log(err))
      .finally(() => setLoaded(true));
  }, [user]);

上下文组件:

import React, {useState, useEffect, createContext} from 'react';
import jwt from 'jsonwebtoken';

/* GLOBAL VARIABLES (CLIENT) */
export const GlobalContext = createContext();

export const GlobalProvider = props => {

    /* ENVIRONMENT API URL */
    const [user, setUser] = useState([]);

    useEffect(() => {
        const getSession = async () => {
            const user = await sessionStorage.getItem('authorization');
            setUser(jwt.decode(user));
    }
    getSession();
    }, [])

    return (
        <GlobalContext.Provider value={[user, setUser]}>
            {props.children}
        </GlobalContext.Provider>
    );
};

【问题讨论】:

    标签: reactjs asynchronous react-hooks react-context use-effect


    【解决方案1】:

    这里的问题是useEffect 正在挂载上运行,而您还没有用户。你只需要防范这种情况

    useEffect(() => {
      if (!user) return;
    
      // use user._id
    },[user])
    

    自然,当 Context 获取用户时,它应该强制重新渲染您的组件,并且随着依赖项发生变化,useEffect 自然应该重新运行。

    【讨论】:

      【解决方案2】:

      在渲染你 GlobalProvider 之前放一个条件,例如:

       return (
          {user.length&&<GlobalContext.Provider value={[user, setUser]}>
              {props.children}
          </GlobalContext.Provider>}
      );
      

      如果用户不是数组,就使用这个

       return (
          {user&&<GlobalContext.Provider value={[user, setUser]}>
              {props.children}
          </GlobalContext.Provider>}
      );
      

      【讨论】:

      • 感谢您的回复,但不幸的是它给了我一个Cannot read property length of null。我想异步函数还没有加载。
      • 为什么是user.length?看起来 user 不会是这里的数组
      • const [user, setUser] = useState([]); ?
      • @FrançoisRichard 啊,我明白了,状态的默认值具有误导性,因为它没有被用作数组(语言的使用也不会暗示它,都是单数)。此外,FWIW,您不希望在上下文中使 user 成为 useEffect 的依赖项,否则您最终会出现获取用户数据的连续循环。
      • 是的,关于循环
      猜你喜欢
      • 2020-01-20
      • 2020-11-08
      • 2021-03-21
      • 2020-10-07
      • 2019-12-05
      • 2020-05-24
      • 2019-11-12
      • 2020-08-08
      相关资源
      最近更新 更多