git://www.github.com/relay-tools/react-router-relay.git
git clone http://www.github.com/relay-tools/react-router-relay
$ svn co --depth empty http://www.github.com/relay-tools/react-router-relay
Checked out revision 1.
$ cd repo
$ svn up trunk
用于响应路由器的中继集成。
这个库只支持中继经典。 有关中继调制解调器的支持,请参阅找到中继功能。
这个库不支持响应路由器 v4,因为响应路由器v4不提供有效的集成点,以便与中继服务器进行有效的数据提取。 另外,与响应路由器v3相比,呈现性能更好,响应路由器v3中的链接订阅逻辑会导致不必要的rerenders与中继一起触发。
应用 useRelay
路由器中间件,在 <Router>
中传递一个中继环境,然后定义中继查询和为每个路由呈现回调:
import { applyRouterMiddleware, /*.. . */ } from'react-router';importuseRelayfrom'react-router-relay';/*.. . */constViewerQueries= { viewer: () =>Relay.QL`query { viewer }`};constWidgetQueries= { widget: () =>Relay.QL`query { widget(widgetId: $widgetId) }`}ReactDOM.render( <Router history={history} render={applyRouterMiddleware(useRelay)} environment={Relay.Store} ><Route path="/" component={Application} queries={ViewerQueries} ><Route path="widgets"><IndexRoute component={WidgetList} queries={ViewerQueries} prepareParams={prepareWidgetListParams} /><Route path=":widgetId" component={Widget} queries={WidgetQueries} render={({ props }) => props ?<Widget {...props} />:<Loading />} /></Route></Route></Router>, container );
react-router-relay
将自动生成与活动反应路由器路由中的所有查询和参数相结合的中继查询配置。 随着查询的全部收集到一个查询配置中,它们将并行地获取,整个页面的数据将加载。
你可以在 https://github.com/taion/relay-todomvc 中找到使用 react-router-relay
进行路由的TodoMVC示例实现。
$ npm install react react-dom react-relay react-router $ npm install react-router-relay
应用 useRelay
路由器中间件,并将中继环境传递到 <Router>
:
importuseRelayfrom'react-router-relay';/*.. . */ReactDOM.render( <Router history={history} routes={routes} render={applyRouterMiddleware(useRelay)} environment={Relay.Store} />, container );
对于需要中继数据的每个路由,在 <Route>
上定义一个 queries
prop。 这些应该与中继查询配置中的查询类似:
constViewerQueries= { viewer: () =>Relay.QL`query { viewer }`};constapplicationRoute= ( <Route path="/" component={Application} queries={ViewerQueries} />);
Relay.Renderer
一样,组件将把查询结果作为道具接收,除了反应路由器的它的他注入道具。
如果你的路由对中继数据没有任何依赖关系,则不要声明 queries
。 唯一需要定义 queries
的任何路由必须有一个中继容器作为它的组件。
在路由器中,可以使用当前路由器状态作为函数的函数来返回计算查询,因此可以在路径或者参数之间进行传递。
<Route component={Widget} getQueries={({ location, params }) =>getWidgetQueries(location, params)}/>路径参数
带有查询及其祖先的路由路径参数将用作中继查询配置的参数:
constWidgetQueries= { widget: () =>Relay.QL`query {widget(widgetId: $widgetId), # $widgetId comes from the path. }`}constWidget=Relay.createContainer(/*.. . */, { fragments: { widget: () =>Relay.QL`fragmentonWidget {name, }` } });// This handles e.g./widgets/3.constwidgetRoute= ( <Route path="widgets/:widgetId" component={Widget} queries={WidgetQueries} />);附加参数
如果查询需要来自位置的其他参数,比如位置查询或者状态,则可以使用 prepareParams
添加这些参数。 你还可以使用 prepareParams
来执行参数的附加转换或者初始化。
prepareParams
方法在中继查询配置上具有与 prepareParams
相同的签名和行为,除这里之外,它还接收当前路由器状态。 预期将返回相同的结果,当给定相同的参数和路由器状态时。
此外,可以在容器上使用路由参数作为变量:
constWidgetList=Relay.createContainer(/*.. . */, { initialVariables: { color:null, size:null, limit:null }, fragments: { viewer: () =>Relay.QL`fragmentonUser {widgets(color: $color, size: $size, first: $limit) {edges {node {name, }, }, }, }` } });functionprepareWidgetListParams(params, { location }) { const { color, size } =location.query; constlimit=location.state&&location.state.limit; return { ...params, color, size: size &&parseInt(size, 10), limit: limit ||10, }; };// This handles e.g./widgets?color=blue&size=3.constwidgetListRoute= ( <Route path="widgets" component={WidgetList} queries={ViewerQueries} prepareParams={prepareWidgetListParams} />);命名组件
对于具有命名组件的路由,将 queries
定义为具有每个组件的查询的对象,按名称:
<Route components={{ foo: FooComponent, bar: BarComponent }} queries={{ foo: FooQueries, bar: BarQueries }}/>呈现回调
你可以将自定义 render
回调传递到你的路由:
<Route component={WidgetList} queries={ViewerQueries} render={({ props }) => props ?<WidgetList {...props} />:<Loading />}/>
除了出现在 Relay.Renderer
上的render
回调外,它具有相同的签名,但当出现时,props
还将包含来自响应路由器的。 Relay.Renderer
一样,你可以返回 undefined
以继续渲染渲染的最后一个视图。
转换时,就绪状态属性(。done
,error
,retry
,stale
) 将反映整个转换的就绪状态。 但是,只要该特定路由的数据准备好,就会填充路由的render
回调中的props
对象。 例如如果转换没有将参数更改为父路由的查询,则该路由的render
回调将具有 props
,即使它的子路由的render
回调可能不在该路径中。
呈现回调的参数对象包含两个额外属性: routerProps
和 element
。routerProps
包含路由器的道具,与 props
不同,无论中继准备状态如何,都会填充。 routerProps
可以用于呈现子路由,而父路由的数据仍在加载,或者者使用路由器中的信息控制中继数据。 element
包含没有中继道具的基线元素,可以用于在路由使用动态组件或者使用路由组件时呈现路由组件:
({ props, routerProps, element }) => { if (!props) { return<Loading {...routerProps} />; } returnReact.cloneElement(element, props); }
使用命名组件时,可以根据每个组件定义这些组件,可以选择忽略不需要自定义呈现回调的组件的回调:
<Route components={{ foo: FooComponent, bar: BarComponent }} queries={{ foo: FooQueries, bar: BarQueries }} render={{ foo: renderFoo }}/>
Relay.Renderer
配置我们通过 <Router>
或者生成的路由器上下文向底层 Relay.Renderer
传递额外的道具。 你可以使用它来控制 Relay.Renderer
上 forceFetch
之类的道具:
<Router history={history} routes={routes} render={applyRouterMiddleware(useRelay)} forceFetch={true} environment={Relay.Store}/>
react-router-relay
对路由对象使用引用相等性来生成查询的唯一名称。 如果 route
对象不维护引用相等性,则可以以在路由上指定一个全局唯一的name
属性来标识它。render
方法尽量轻轻,并尽可以能多地在子组件中使用。