到目前为止,我们已经介绍了两个有助于声明数据的部分:
要使用这些部分构建一个完整的GraphQL查询,我们可以发送给服务器来获取数据,我们需要使用 Relay.RootContainer。
Relay.RootContainer 是一个 React 组件, 给定一个 Component
和一个
route
, 它会尝试获取需要的数据以渲染一个 Component
的实例。
ReactDOM.render( <Relay.RootContainer Component={ProfilePicture} route={profileRoute} />, container );
当上述 Relay.RootContainer 被渲染时, 将构造一个查询并发送给GraphQL服务器。一旦获取了所有必需的数据,
ProfilePicture
就会被渲染。带有片段的 Props 将包含从服务器获取的数据。
如果 Component
或 route
发生变化,
Relay.RootContainer 将立即开始尝试实现新的数据要求。
Relay.RootContainer 接受三个可选回调作为 props 使我们对渲染行为进行更细致的控制。/p>
renderLoading
#
Relay.RootContainer在无法立即实现渲染所需的数据时,会呈现加载状态。这通常发生在初始渲染时,但也可能发生在
Component
或 route
改变时。
B默认情况下,在加载初始渲染的数据时,不会渲染任何内容。如果前一组的
Component
和 route
实现并被渲染, 默认行为是继续呈现
渲染之前的视图。
我们可以通过提供 renderLoading
prop 来改变这种行为:
<Relay.RootContainer Component={ProfilePicture} route={profileRoute} renderLoading={function() { return <div>Loading...</div>; }} />
此代码段配置 Relay.RootContainer 以便在需要提取数据时呈现 "Loading..." 。
renderLoading
回调可以返回
undefined
模拟预设行为. 注意,这与 renderLoading
回调返回的 null
有所不同,
当数据正在加载时,即使呈现前面的视图,也不会呈现为空白。
renderFetched
#
当渲染所需的所有数据变得可用时, Relay.RootContainer 将默认渲染提供的组件 Component
。 但是,我们可以通过向
renderFetched
prop 提供回调来更改此行为:
<Relay.RootContainer Component={ProfilePicture} route={profileRoute} renderFetched={function(data) { return ( <ScrollView> <ProfilePicture {...data} /> </ScrollView> ); }} />
这段代码将配置 Relay.RootContainer 当数据准备好的时候,把 ProfilePicture
渲染在一个 ScrollView
组件里面
renderFetched
回调总是调用一个 data
参数, 它是一个从 propName
映射到查询数据的对象。 预期
renderFetched
回调会使用它们来渲染提供的 Component
(例如 JSX 扩展属性特性).
附注
尽管我们能在
renderFetched
中存取data
对象,但实际的数据被刻意隐藏起来,这能防止renderFetched
在Component
声明片段上建立一个隐含的依赖关系。
renderFailure
#
如果有错误发生,会中断 Relay.RootContainer 获取渲染 Component
需要的数据 ,
则默认情况下不会呈现任何内容。误处理行为可以通过向 renderFailure
prop 提供回调来配置:
<Relay.RootContainer Component={ProfilePicture} route={profileRoute} renderFailure={function(error, retry) { return ( <div> <p>{error.message}</p> <p><button onClick={retry}>Retry?</button></p> </div> ); }} />
renderFailure 回调有两个参数: 一个 Error
对象和重试请求的函数。如果错误是在服务器响应中传递的服务器错误, 检查
error.source
,确定响应负载是否可用。
就像大多数 Relay API一样,, Relay.RootContainer
尝试在向服务器发送请求之前使用客户端存储解析数据。如果我们想要强制服务器请求,即使数据在客户端上可用,我们可以使用 forceFetch
布尔 prop.
<Relay.RootContainer Component={ProfilePicture} route={profileRoute} forceFetch={true} />
当 forceFetch
为真时, Relay.RootContainer将始终向服务器发送一个请求。但是,如果所有需要呈现的数据在客户端上也可用,renderFetched
则仍可在服务器请求完成之前调用。
<Relay.RootContainer Component={ProfilePicture} route={profileRoute} forceFetch={true} renderFetched={function(data, readyState) { var isRefreshing = readyState.stale; return ( <ScrollView> <Spinner style={{display: isRefreshing ? 'block' : 'none' }} <ProfilePicture {...data} /> </ScrollView> ); }} />
当 forceFetch
为真并且 renderFetched
被调用作为可用的客户端数据的结果时,使用
renderFetched
具有 stale
布尔属性的第二个参数来调用。 如果 renderFetched
在强制服务器请求完成之前调用 ,则stale
属性为 true。
Relay.RootContainer 还支持 onReadyStateChange
prop which
它可以让我们在满足数据需求的同时接收详细的事件。
在我们的下一个指南 准备状态 中了解如何使用onReadyStateChange
。