Контекст React возвращает исходное состояние каждый раз, используя его - несмотря на setState - PullRequest
1 голос
/ 23 марта 2020

Я создал этот простой компонент аутентификации. Когда приложение обновляется и ContextProvider загружается useEffect метод запускается и устанавливает пользователя, вошедшего в систему.

Посмотрите на код

import React, { createContext, useState, useContext, useEffect } from 'react';
import User from 'utils/User/User';
import useLocale from 'store/LocaleContext';
import { tokenKey } from 'consts';

const AuthContext = createContext();

const initialState = { auth: false, user: null };

export const AuthContextProvider = ({ children }) => {
  const [state, setState] = useState(initialState);
  const { setLanguage } = useLocale();

  const loginUser = user => {
    setLanguage(user.getLanguage());
    user.login();
    setState({ ...state, user: user, auth: true });

    setTimeout(() => {
      logOutUser();
    }, 2000);
  };

  const logOutUser = () => {
    console.log(state.user, state); // Output: null, {auth: false, user: null}
    state.user.logout();
    setState(initialState);
  };

  useEffect(() => {
    User.Credentials.loginWithToken(localStorage.getItem(tokenKey))
      .then(data => data.data)
      .then(data => {
        if (data.success && data.user) {
          loginUser(new User(data.user));
        }
      })
      .catch(err => {
        console.log(err);
        logOutUser();
      });
  }, []);

  return (
    <AuthContext.Provider
      value={{
        auth: state.auth,
        user: state.user,
        loginUser,
        logout: logOutUser
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};

export default () => useContext(AuthContext);

loginUser метод выполняется правильно, но затем я хочу проверить logoutUser функцию. Поэтому я решил запустить функцию logoutUser через 2 секунды после входа в систему, но она читает старое состояние.

Когда я регистрирую state и state.user, я получаю вывод: null, {auth: false, user: null}. Итак, как вы можете видеть, он читает initialState или состояние не меняется.

Можете ли вы сказать мне, в чем проблема и что я делаю неправильно?

Любая помощь будет оценена

1 Ответ

0 голосов
/ 23 марта 2020

Две вещи. Оба связаны с асинхронностью useState.

  1. Вам необходимо использовать функцию в качестве первого параметра, переданного в setState. React будет вызывать его с текущим состоянием во время вызова и ожидать, что вы вернете объект для слияния в состояние.

setState(state => ([...state, user: user, auth: true]));

Вам нужно использовать Крюк useEffect(), чтобы убедиться, что вы получаете обновленную версию состояния, когда вы console.log().

useEffect(() => { console.log(state) }, [state]);

Дайте мне знать если это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...