同步加载React Provider组件的模式

时间:2019-03-07 16:30:04

标签: reactjs typescript apollo-client react-hooks react-context

我的:brain:在爆炸。

在我的应用程序的根目录中,我想设置一个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 个答案:

答案 0 :(得分:1)

您声明上下文可以接受IUserContextnull,这就是为什么需要爆炸的原因。

从上下文解开User的一种解决方案是,如果用户为null,则引发异常(无论如何都不会发生?)。然后Typescript会推断您的用户实际上不是null,而是实际的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
}
相关问题