如何让 Relay 和 React Routing 正常工作?
How to make Relay and React Routing work properly?
我开始使用 Relay 并尝试使我的路由正常工作。
不幸的是,我运气不佳。
这是我收到的错误:
Uncaught TypeError: Component.getFragment is not a function
这是我提供的代码供您参考:
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
的建议进行了一些更改,如下所示。但这引发了以下两个问题:
- 当我更改路由并且
Home
以外的组件被 App
组件渲染时会发生什么?
- 我现在收到这个错误:
Warning: RelayContainer: Expected prop store
to be supplied to
Home
, but got undefined
. Pass an explicit null
if this is
intentional.
更改如下:
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')}
}
`
}
});
Fragment定义实际上并没有获取Components作为参数,而是容器的变量映射,你只需要使用它们来根据变量值有条件的fragments。
中继路由查询不接受任何参数。
这是您需要进行的更改。
中继中的路由查询只需要指定您要在此路由中检索的根查询,无需分片。
index.jsx
const AppQueries = {
store: () => Relay.QL `query {
store
}`
};
你的App组件实际上没有使用任何中继数据,所以你可以只导出普通组件而不是容器。
export default class App extends Component {
如果你需要传递一些中继数据给它,你不需要包含子片段,因为只有当你直接将其他容器渲染为直接子容器时才需要包含片段(而不是 this.props.children).
然后在 Router 中您需要将查询移动到 Home。
ReactDOM.render(
<RelayRouter history={browserHistory}>
<Route path='/' component={App}>
<IndexRoute component={Home} queries={AppQueries} />
</Route>
</RelayRouter>,
document.getElementById('ch-root'));
我开始使用 Relay 并尝试使我的路由正常工作。 不幸的是,我运气不佳。
这是我收到的错误:
Uncaught TypeError: Component.getFragment is not a function
这是我提供的代码供您参考:
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
的建议进行了一些更改,如下所示。但这引发了以下两个问题:
- 当我更改路由并且
Home
以外的组件被App
组件渲染时会发生什么? - 我现在收到这个错误:
Warning: RelayContainer: Expected prop
store
to be supplied toHome
, but gotundefined
. Pass an explicitnull
if this is intentional.
更改如下:
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')}
}
`
}
});
Fragment定义实际上并没有获取Components作为参数,而是容器的变量映射,你只需要使用它们来根据变量值有条件的fragments。
中继路由查询不接受任何参数。
这是您需要进行的更改。
中继中的路由查询只需要指定您要在此路由中检索的根查询,无需分片。
index.jsx
const AppQueries = {
store: () => Relay.QL `query {
store
}`
};
你的App组件实际上没有使用任何中继数据,所以你可以只导出普通组件而不是容器。
export default class App extends Component {
如果你需要传递一些中继数据给它,你不需要包含子片段,因为只有当你直接将其他容器渲染为直接子容器时才需要包含片段(而不是 this.props.children).
然后在 Router 中您需要将查询移动到 Home。
ReactDOM.render(
<RelayRouter history={browserHistory}>
<Route path='/' component={App}>
<IndexRoute component={Home} queries={AppQueries} />
</Route>
</RelayRouter>,
document.getElementById('ch-root'));