React,Apollo 2,GraphQL,身份验证系统

时间:2017-12-09 16:22:53

标签: reactjs react-native graphql apollo react-apollo

我有这段代码:https://codesandbox.io/s/507w9qxrrl

我不明白:

1)如何在以下情况下重新渲染()Menu 组件:

this.props.client.query({
  query: CURRENT_USER_QUERY,
  fetchPolicy: "network-only"
});

如果我登录(),我希望我的Menu组件重新呈现()本身。但没什么。如果我点击Home链接,它会重新渲染()。我怀疑是因为我用它来渲染它:

<Route component={Menu} />

用于在react-routers道具中拥抱它。这是错的吗?

2)如果未经过身份验证,如何阻止Menu组件查询(例如:localStorage中没有令牌);我在Menu组件中使用了此代码:

export default graphql(CURRENT_USER_QUERY)(Menu);

3)这是正确的方法吗?

1 个答案:

答案 0 :(得分:0)

我会考虑将CURRENT_USER_QUERY移动到App.jsx组件中。它与我下面的内容类似。

我的AppContainer是我的父组件。它检查用户是否已登录。然后,它可以获取查询结果并将用户/角色传递给子组件(即您的案例中的Menu.jsx)。这样,您可以检查用户是否已登录并随后更改要显示它们的组件

const loggedInUser = gql`
  query loggedInUser{
    user {
      id
      role
    }
  }`


export default graphql(loggedInUser, { options: {fetchPolicy: 'network-only' }})(AppContainer)

以下是AppContainer.jsx

的更完整示例
import React from 'react';
import { graphql } from 'react-apollo';
import { Route, Switch, Redirect } from 'react-router-dom';

import AppNav from 'AppNav';
import ExampleContainer from 'ExampleContainer';
import ExampleContainerTwo from 'ExampleContainerTwo';
import LoginPage from 'LoginPage';

const AppContainer = ({ data }) => {
  if (data.loading) {
    return <div>Loading...</div>
  }

  //checks if user is logged in
  if (data.user) {
    return (
      <div id="app-container">
        <AppNav adminUser={data.user.role === 'ADMIN' ? true : false} />
        <div className="content">
          <Switch>
            <Route exact path="/app/" component={ExampleContainer} />
            <Route path="/app/example-two" component={ExampleContainerTwo} />
          </Switch>
        </div>
      </div>
    )
  }

  return <LoginPage handleUserLoggedIn={() => data.refetch()} />
}

const loggedInUser = gql`
      query loggedInUser{
        user {
          id
          role
        }
      }`

export default graphql(loggedInUser, { options: {fetchPolicy: 'network-only' }})(AppContainer)