Шаблон для синхронной загрузки реагирующего компонента провайдера - PullRequest
0 голосов
/ 07 марта 2019

Мой: мозг: взрывается.

В корне моего приложения я хочу установить UserProvider (упрощенная версия ниже).

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

При следующей реализации мне необходимо выполнять нулевую проверку при каждом использовании:

  const userContext = useContext(UserContext)
  const userId = userContext!.id   // I do not want that bang(!)

Моя текущая реализация:

interface IUserContext {
  id: string
  email: string
}

const UserContext = React.createContext<IUserContext|null>(null);

const UserProvider: React.FC = ({ children }) => {
  const [user, setUser] = useState(initalContext);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    client
      .query<CurrentUserQuery>({
        query: currentUserQuery
      })
      .then((res) => {
        if (res.error) {
          logger(res.error);
        }
        if (res.data.me) {
          setUser(res.data.me);
          setLoading(false);
        }
      });
  });

  if (loading) {
    return <Loading />;
  }

  return <UserContext.Provider value={user}>{children}</UserContext.Provider>;
};

Я знаю, что могу сделать что-то вроде:

const emptyUser = {
  id: '',
  email: ''
}

const UserContext = React.createContext(emptyUser);

Но это пахнет очень плохо для меня.

Кто-нибудь пришел?с чистым решением этого?

Спасибо!

1 Ответ

1 голос
/ 07 марта 2019

Вы объявили, что ваш контекст принимает IUserContext или null, поэтому вам нужен взрыв!.

Решением для разворачивания User из контекста было бы выбрасывание исключения, если пользователь null (что не должно произойти в любом случае?). Тогда Typescript сделает вывод, что ваш пользователь на самом деле не нулевой, а фактический User

const userContext = createContext<User | null>(null)

const useUser = (): User => {
  const user = useContext(userContext)

  if (user === null) {
    throw new Error('You forgot the provider')
  }

  return user // This is a User
}
...