【问题标题】:How to make Relay and React Routing work properly?如何让 Relay 和 React Routing 正常工作?
【发布时间】:2016-08-09 18:59:03
【问题描述】:

我开始使用 Relay 并尝试使我的路由正常工作。 不幸的是,我运气不佳。

这是我得到的错误:

未捕获的类型错误:Component.getFragment 不是函数

这是我的代码供您参考:

index.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import Relay from 'react-relay';
import {Router, Route, IndexRoute, browserHistory} from 'react-router';
import {RelayRouter} from 'react-router-relay';

import App from './modules/app';
import Home from './modules/home';

const AppQueries = {
  store: (Component) => Relay.QL `query {
    store {
      ${Component.getFragment('store')}
    }
  }`
};

ReactDOM.render(
  <RelayRouter history={browserHistory}>
    <Route path='/' component={App} queries={AppQueries}>
      <IndexRoute component={Home}/>
    </Route>
  </RelayRouter>, 
document.getElementById('ch-root'));

app.jsx

import React, {Component} from 'react';
import Relay from 'react-relay';
import Header from './ui/header';
import Footer from './ui/footer';

class App extends Component {
  render() {
    return (
      <div id="ch-container">
        <Header/>
        <section id="ch-body">
          {this.props.children}
        </section>
        <Footer/>
      </div>
    );
  }
}

App = Relay.createContainer(App, {
  fragments: {
    store: (Component) => Relay.QL `
      fragment on Store {
        ${Component.getFragment('store')}
      }
     `
  }
});

export default App;

home.jsx

import React, {Component} from 'react';
import Relay from 'react-relay';
import Loader from './ui/loader';
import AccountSelector from './account/account-selector';

const APP_HOST = window.CH_APP_HOST;
const CURR_HOST = `${window.location.protocol}//${window.location.host}`;

class Home extends Component {
  state = {
    activeAccount: null,
    loading: true
  }

  render() {
    const {activeAccount, loading} = this.state;

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

    if (!activeAccount && !loading) {
      return <AccountSelector/>;
    }

    return (
      <h1>Hello!</h1>
    );
  }
}

Home = Relay.createContainer(Home, {
  fragments: {
    store: () => Relay.QL `
      fragment on Store {
        accounts {
          unique_id,
          subdomain
        }
      }
     `
  }
});

export default Home;

更新

我做了一些freiksenet 建议的更改,如下所示。但这引发了以下两个问题:

  1. 当我更改路由并且Home 以外的组件被App 组件渲染时会发生什么?
  2. 我现在收到此错误:

警告:RelayContainer:预期的道具 store 将提供给 Home,但得到了undefined。如果是,则传递显式 null 故意的。

以下是更改:

index.jsx

const AppQueries = {
  store: () => Relay.QL `query {
    store 
  }`
};

app.jsx

import Home from "./home";

...

App = Relay.createContainer(App, {
  fragments: {
    store: () => Relay.QL `
      fragment on Store {
        ${Home.getFragment('store')}
      }
     `
  }
});

【问题讨论】:

  • 这个错误意味着它不知道Component是什么。您必须以与导入 AppHome 类似的方式导入它。我假设错误是在index 文件上生成的?
  • @Moon 对您的更新 1 的回复:问题 2:您没有通过任何对 Home 组件的查询。在 index.jsx 文件中,将 &lt;IndexRoute component={Home}/&gt; 更改为 &lt;IndexRoute component={Home}/&gt; queries={AppQueries}。问题 1:正如@freiksenet 已经提到的,App 不一定是容器。 App 渲染的其他组件只需要定义必要的片段。

标签: reactjs react-router relayjs react-router-relay


【解决方案1】:

Fragment定义实际上并没有将Components作为参数,而是容器的变量映射,您只需要使用它们就可以根据变量值获得条件片段。

中继路由查询不接受任何参数。

这是您需要进行的更改。

Relay 中的路由查询只需要指定您要在此路由中检索的根查询,无需片段。

index.jsx

const AppQueries = {
  store: () => Relay.QL `query {
    store 
  }`
};

您的 App 组件实际上不使用任何中继数据,因此您可以只导出普通组件而不是容器。

export default class App extends Component {

如果您需要将一些 Relay 数据传递给它,则不需要包含子片段,因为仅当您将其他容器直接渲染为直接子容器(而不是 this.props.children)时才需要包含片段.

然后在路由器中,您需要将查询移动到主页。

ReactDOM.render(
  <RelayRouter history={browserHistory}>
    <Route path='/' component={App}>
      <IndexRoute component={Home} queries={AppQueries} />
    </Route>
  </RelayRouter>, 
document.getElementById('ch-root'));

【讨论】:

  • 非常感谢您的回复。我按照建议更新了我的代码,然后用新的观察更新了我的问题。
  • @Moon 啊哈。看来我误解了你想要做的事情。现已更正。
猜你喜欢
  • 1970-01-01
  • 2019-04-27
  • 2019-07-17
  • 2015-05-08
  • 2020-08-27
  • 2018-06-11
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多