如何将 Apollo 数据和 React Router 4 url​​ 参数传递给我的组件

Posted

技术标签:

【中文标题】如何将 Apollo 数据和 React Router 4 url​​ 参数传递给我的组件【英文标题】:How can I pass Apollo data and React Router 4 url params to my components 【发布时间】:2018-01-01 00:49:06 【问题描述】:

我正在使用 React Router V4 和 apollo 客户端。我有几条被认为是私有的路线。我在它们自己的组件中有这些路由。我使用 withRouter() 来包装 PrivateRoute 组件,以便我得到所有传递下来的路由内容。我还将其包装在 graphql 查询中,以便我知道用户已登录。我的问题是我似乎无法同时从 graphql 和路线数据中获取数据。

以这种方式定义路线我得到了阿波罗数据,但不是匹配:id <Route exact path="/people/:id" render=() => <Person ...this.props /> />

如果我将路线更改为此,我会得到参数 id,但我的道具中没有阿波罗数据 <Route ...this.props exact path="/people/:id" component=Person />

这是我的主路由组件

const Routes = () => (
  <Router>
    <div>
      <Switch>
        <Route exact path="/" component=Home />
        <Route path="/login" component=Login />
        <Route path="/create-account" component=CreateUser />
        <PrivateRouteContainer />
      </Switch>
    </div>
  </Router>
);

这是我的 PrivateRoute 和 PrivateRouteContainer

class PrivateRoute extends Component 
  render() 
    if (this.props.data.loading) 
      return <Loading />;
     else if (this.props.data.user) 
      return (
        <div>
          <VerticalNavFixed />
          <article className="docs-content">
            <Switch>
              <Route ...this.props exact path="/people/:id" component=Person />
            </Switch>
          </article>
        </div>
      );
    
    return <Redirect to= pathname: '/login', state:  from: this.props.location   />;
  



const PrivateRouteContainer = graphql(userQuery,  options:  fetchPolicy: 'network-only'  )(withRouter(PrivateRoute));

【问题讨论】:

【参考方案1】:

事实证明,我的路线已经有用户推送到它,这就是我需要确保路线安全的全部内容。此外,我需要将我的其他组件包装在不同的查询中,因此我不需要将现有查询数据传递给组件。我和这个一起去了

&lt;Route exact path="/people/:id" render=() =&gt; &lt;Person ...this.props /&gt; /&gt;

然后在我的组件中,我用选项中的 params 变量包装它,这使得查询等待这个参数。

export const PersonWithData = graphql(PersonQuery, 
  options: ownProps => ( variables:  id: ownProps.match.params.id  ),
)(Person);

【讨论】:

【参考方案2】:

一种解决方案是在React.cloneElement 函数中结合路由props 和query 的props。在您的情况下,它可能如下所示:

class PrivateRoute extends Component 
  render() 
    if (this.props.data.loading) 
      return <Loading />;
     else if (this.props.data.user) 
      return (
        <div>
          <VerticalNavFixed />
          <article className="docs-content">
            <Switch>
              <Route path="/people/:id" render=(props) => return React.cloneElement(<Person />, user: this.props.data.user, ...props) />
            </Switch>
          </article>
        </div>
      );
    
    return <Redirect to= pathname: '/login', state:  from: this.props.location   />;
  



const PrivateRouteContainer = graphql(userQuery,  options:  fetchPolicy: 'network-only'  )(withRouter(PrivateRoute));

【讨论】:

谢谢,我还发布了我使用的解决方案。我现在想远离使用 React.cloneElement。

以上是关于如何将 Apollo 数据和 React Router 4 url​​ 参数传递给我的组件的主要内容,如果未能解决你的问题,请参考以下文章

如何管理 react + apollo 应用程序的状态

React - Apollo 客户端,如何将查询结果添加到状态

Graphql,react-apollo如何在加载组件状态时将变量传递给查询

使用 Express-GraphQL 和 React-Apollo 订阅 GraphQL

React - Apollo,如何将 Object 放入查询中?

你如何动态控制 react apollo-client 查询启动?