如何在React Apollo客户端中设置全局支持

时间:2019-02-12 13:37:02

标签: reactjs ecmascript-6 graphql react-apollo apollo-client

我正在使用react和react-apollo客户端。

这是我的主要路线文件

const PrivateRoute = ({ component, isAuthed, ...rest }) => {
  console.log({ isAuthed })
  return (
    <Route {...rest} exact
      render = {(props) => (
        isAuthed ? (
          <div>
            {React.createElement(component, props)}
          </div>
        ) :
          (
            <Redirect
              to={{
                pathname: '/login',
                state: { from: props.location }
              }}
            />
          )
      )}
    />
  )
}

class App extends Component {
  state = {
    isAuthed: false
  }

  async componentWillMount() {
    this.setState({ isAuthed: true })
  }

  render() {
    const { isAuthed } = this.state
    return (
        <div style={{ direction: direction }}>
          <Header {...this.props} history={history}/>
          <Router history={history}>
            <Switch>
              <Route exact path="/" render={() => <Redirect to="/dashboard" />} />
              <Route path="/login" component={Login}/>
              <PrivateRoute isAuthed={isAuthed} path="/dashboard" component={Dashboard} />
              <PrivateRoute isAuthed={isAuthed} path="/AdminManagement" component={Admin} />
            </Switch>
          </Router>
        </div>
    )
  }
}

export default compose(
  graphql(SET_SESSION, { name: 'setSession' })
)((withNamespaces)('common')(App))

现在,当我在登录组件中登录时,我需要将isAuthed设置为true,它位于我的主路由文件中(在上面)

我该如何对React Apollo客户端执行此操作?

1 个答案:

答案 0 :(得分:2)

不幸的是,React或Apollo中没有“全局”道具之类的东西。如果您想实现类似于示例的功能(即从登录组件更新根组件上的状态),您是否考虑过将方法传给所述组件并在GraphQL突变解决时将其触发?

我将对此进行介绍,但是请注意,这都是伪代码,只是概述了可以用来解决此问题的多种方法之一:

App.js

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            userInfo: {},
            authed: false,
        }
        this.modifyUserInfo = this.modifyUserInfo.bind(this);
    }

    modifyUserInfo(userInfo) {
        this.setState(state => ({
            ...state,
            userInfo,
            authed: true,
        }))
    }

    render() {
        return (
            // Render all your routes and everything...
            <LoginComponent loginCb={modifyUserInfo} />
        )
    }
}

登录组件

const Login = props => {
    return (
            <Mutation mutation={loginMutation}>
                {(login) => {
                    <form onSubmit={(e) => {
                        e.preventDefault();
                        login()
                            .then(res => {
                                if (res.userInfo) {
                                    props.loginCb(res.userInfo);
                                }
                            })
                            .catch(err => {
                                console.log(err)
                            })
                    }}>
                        {/* Add the rest of your login form */}
                        <button type="submit"/>
                    </form>
                }}
            </Mutation>
    )
}

您是否考虑过使用Apollo缓存并将用户信息注入到相关组件中,而不是将用户身份验证信息存储在根状态下?就像我说的那样,有很多很多不同的方法来解决这个问题。