Jeer
@Jeer
уверенный пользователь

Почему не обновляется страница react-context?

Всем привет, разбираюсь с реактом
Добавил глобальный контекст пользователя (это класс, но я переписывал на функцию, разницы нет)
Когда меняю через сеттер поле в объекте контекста (UserService), то не происходит автоматическое обновление страницы. Весь App обернут в этот глобальный контекст.

Пример кода выложил https://codesandbox.io/s/compassionate-merkle-rnlo...

Когда получаю пользователя
const userService = useUser();
Могу изменить лишь свойства, доступные как publiс. Я пробовал добавить публичное свойство с меткой времени, чтобы объект явно был другим, это не помогает.
Если я получаю провайдер, то через него так же не могу установить новый объект, так как он все равно считается readonly.
Помогите, пожалуйста
  • Вопрос задан
  • 340 просмотров
Решения вопроса 1
Jeer
@Jeer Автор вопроса
уверенный пользователь
Тут тоже никто не ответил, в общем, я переделал свой сервис на функцию вот так:
import UserModel from "../models/user.model";
import React from "react";

const UserService = () => {
  const localStorageKey = "user";
  const [user, setStateUser] = React.useState<UserModel | null>(null);

  function getUser(): UserModel | null {
    if (user != null) return user;

    const usr = localStorage.getItem(localStorageKey);
    if (usr != null) setStateUser(new UserModel(JSON.parse(usr)));

    return user;
  }

  function setUser(val: UserModel) {
    localStorage.setItem(localStorageKey, JSON.stringify(val));
    setStateUser(val);
  }

  function logOut(){
    localStorage.removeItem(localStorageKey);
    setStateUser(null);
  }

  function isAuth(): boolean {
    return user != null && user.userName != null;
  }

  function hasRole(roleId: number): boolean {
    if (!user || !isAuth || user.roles == null) return false;
    return user.roles.indexOf(roleId) > -1;
  }

  return{
    getUser,
    setUser,
    logOut,
    isAuth,
    hasRole
  }
}

export default UserService;


А свой провайдер с контекстом сделал вот так:
import React, { useContext } from "react";
import UserService from "../services/user.service";

const userContext = React.createContext(null);

export const UserProvider = ({ children }: any) => {
  const userService = UserService();

  return (
    <userContext.Provider value={userService}>
      {children}
    </userContext.Provider>
  );
};

export const useUser = () => useContext(userContext);

Тут действительно контекст создается с null, как по мне выглядит довольно криво, но только так работает
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Alexandroppolus
@Alexandroppolus
кодир
У тебя в провайдере сидит постоянный экземпляр. Когда ты что-то меняешь внутри этого экземпляра, Реакту пофиг.
Вариантов два:
1) При любом изменении чего-либо в составе объекта надо менять весь объект в контексте. В провайдер попадает новое значение, и это заставляет перерендериваться все компоненты, которые используют этот контекст.
2) Подключить MobX и просто сделать поля в userService наблюдаемыми, а компоненты обернуть в observer. Удобно и просто.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы