根容器

到目前为止,我们已经介绍了两个有助于声明数据的部分:

  • Relay.Route 允许我们声明查询根。
  • Relay.Container 让组件声明片段。

要使用这些部分构建一个完整的GraphQL查询,我们可以发送给服务器来获取数据,我们需要使用 Relay.RootContainer

组件和路由 #

Relay.RootContainer 是一个 React 组件, 给定一个 Component 和一个 route, 它会尝试获取需要的数据以渲染一个 Component 的实例。

ReactDOM.render(
  <Relay.RootContainer
    Component={ProfilePicture}
    route={profileRoute}
  />,
  container
);

当上述 Relay.RootContainer 被渲染时, 将构造一个查询并发送给GraphQL服务器。一旦获取了所有必需的数据, ProfilePicture 就会被渲染。带有片段的 Props 将包含从服务器获取的数据。

如果 Componentroute 发生变化, Relay.RootContainer 将立即开始尝试实现新的数据要求。

渲染回调 #

Relay.RootContainer 接受三个可选回调作为 props 使我们对渲染行为进行更细致的控制。/p>

renderLoading #

Relay.RootContainer在无法立即实现渲染所需的数据时,会呈现加载状态。这通常发生在初始渲染时,但也可能发生在 Componentroute 改变时。

B默认情况下,在加载初始渲染的数据时,不会渲染任何内容。如果前一组的 Componentroute 实现并被渲染, 默认行为是继续呈现 渲染之前的视图。

我们可以通过提供 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 对象,但实际的数据被刻意隐藏起来,这能防止 renderFetchedComponent 声明片段上建立一个隐含的依赖关系。

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