So far, we’ve covered two pieces that each contribute to declaring data:
到目前为止,我们已经讲了两个重要的部分,都是用来声明数据的:
- Relay.Route lets us declare query roots.声明query roots
- Relay.Container lets components declare fragments. 让components声明fragments
To use these pieces to construct a full-fledged GraphQL query that we can send to the server to fetch data, we need to use the Relay.RootContainer.
想使用这两部分去构建一个完整的可以从服务器端获取数据的GraphQL query,我们还需要Relay.RootContainer。
Component and Route
Relay.RootContainer is a React component that, given a Component
and a route
, attempts to fulfill the data required in order to render an instance of Component
.
Relay.RootContainer是一个React component,可以接收一个component和一个route作为props,去获取所需要的数据并渲染这个component的实例。
React.render(
<Relay.RootContainer
Component={ProfilePicture}
route={profileRoute}
/>,
container
);
When the Relay.RootContainer above is rendered, Relay will construct a query and send it to the GraphQL server. As soon as all required data has been fetched, ProfilePicture
will be rendered. Props with fragments will contain data that was fetched from the server.
当上面的Relay.RootContainer被渲染时,Relay将构建一个query发送给GraphQL server。一旦数据都获取到了,ProfilePicture
将被渲染。其中与fragments对应的props中将包含从服务器端获取来的数据。
If either Component
or route
ever changes, Relay.RootContainer will immediately start attempting to fulfill the new data requirements.
如果 Component
或 route
改变了的话, Relay.RootContainer会立刻尝试满足新的数据需求。
Render Callbacks
Relay.RootContainer accepts three optional callbacks as props that give us more fine-grained control over the render behavior.
Relay.RootContainer还可以接收三个可选的回调作为props,在渲染的过程中给我们更细的颗粒度控制。
renderLoading
Relay.RootContainer renders the loading state whenever it cannot immediately fulfill data needed to render. This often happens on the initial render, but it can also happen if either Component
or route
changes.
Relay.RootContainer 在完全获取到所需的数据之前是有一个过程的。这经常发生在初始化或者Component
、 route
改变的时候。
By default, nothing is rendered while loading data for the initial render. If a previous set of Component
and route
were fulfilled and rendered, the default behavior is to continue rendering the previous view.
默认情况,在初始化加载数据的过程中不会显示什么。如果之前的Component
and route
已经被渲染过了,默认的行为是再加载新数据时继续显示原来的画面。
We can change this behavior by supplying the renderLoading
prop:
我们可以通过renderLoading
改变默认加载的行为:
<Relay.RootContainer
Component={ProfilePicture}
route={profileRoute}
renderLoading={function() {
return <div>Loading...</div>;
}}
/>
This snippet configures Relay.RootContainer to render the “Loading…” text whenever it needs to fetch data.
它表示在数据加载时显示”Loading…”
A renderLoading
callback can simulate the default behavior by returning undefined
. Notice that this is different from a renderLoading
callback that returns null
, which would render nothing whenever data is loading, even if there was a previous view rendered.
renderLoading
回调可以用返回undefined
来模拟默认的行为。注意它与返回null
是不同的,它将什么都不会显示,即便原本之前有视图被显示。
renderFetched
When all data necessary to render becomes available, Relay.RootContainer will render the supplied Component
by default. However, we can change this behavior by supplying a callback to the renderFetched
prop:
当所有需要的数据准备好时,Relay.RootContainer将默认渲染prop中的Component
。但是我们可以通过renderFetched
改变这一行为。
<Relay.RootContainer
Component={ProfilePicture}
route={profileRoute}
renderFetched={function(data) {
return (
<ScrollView>
<ProfilePicture {...data} />
</ScrollView>
);
}}
/>
This snippet configures Relay.RootContainer to render ProfilePicture
within a ScrollView
component as soon as data is ready.
它将在数据准备好时,使ProfilePicture
在ScrollView
component中一起渲染。
The renderFetched
callback is always called with a data
argument, which is an object mapping from propName
to query data. It is expected that the renderFetched
callback renders the supplied Component
with them (e.g. using the JSX spread attributes feature).
renderFetched
回调通常有一个data
参数,它是一个保存propName
到查询数据映射的对象。用于把data
传给被用来渲染的component
。
Note
Even though we have access to the
data
object inrenderFetched
, the actual data is intentionally opaque. This prevents therenderFetched
from creating an implicit dependency on the fragments declared byComponent
.
尽管我们在renderFetched
中有访问data
对象的权利,实际的data是有意不透明的。它可以防止renderFetched
在Component
声明的fragment上创建隐含的依赖关系。
renderFailure
If an error occurs that prevents Relay.RootContainer from fetching the data required for rendering Component
, nothing will be rendered by default. Error handling behavior can be configured by supplying a callback to the renderFailure
prop:
如果在Relay.RootContainer 获取数据并渲染的过程中发生了错误,默认情况下什么也不会被渲染出来。可以通过renderFailure
来做错误处理。
<Relay.RootContainer
Component={ProfilePicture}
route={profileRoute}
renderFailure={function(error, retry) {
return (
<div>
<p>{error.message}</p>
<p><button onClick={retry}>Retry?</button></p>
</div>
);
}}
/>
The renderFailure
callback is called with two arguments: an Error
object and a function to retry the request. If the error was the result of a server error communicated in the server’s response, the response payload is available for inspection on error.source
.
renderFailure
的回调中可以使用两个参数,一个Error
对象,一个retry函数。如果error是服务器端数据通讯返回的错误,可以通过error.source
进一步查看错误原因。
Force Fetching
Like most of the Relay APIs, Relay.RootContainer attempts to resolve data using the client store before sending a request to the server. If we instead wanted to force a server request even if data is available on the client, we could use the forceFetch
boolean prop.
像大多数Relay API一样,Relay.RootContainer在向服务器端发送请求之前,会先在客户端store中尝试获取数据。如果我们想强制其每次都去服务器端获取数据,不论本地是否有的话,我们可以用forceFetch
。
<Relay.RootContainer
Component={ProfilePicture}
route={profileRoute}
forceFetch={true}
/>
When forceFetch
is true, Relay.RootContainer will always send a request to the server. However, if all the data required to render is also available on the client, renderFetched
may still be called before the server request completes.
当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>
);
}}
/>
When forceFetch
is true and renderFetched
is called as a result of available client data, renderFetched
is called with a second argument that has a stale
boolean property. The stale
property is true if renderFetched
is called before the forced server request completes.
当forceFetch
为真并且renderFetched
被回调,它回调时还有第二个参数,其中包含了布尔类型stale。renderFetched
在强制请求服务器数据全部返回以前,stale为真。
Ready State Change
Relay.RootContainer also supports the onReadyStateChange
prop which lets us receive fine-grained events as they occur while fulfilling the data requirements.
Relay.RootContainer同样支持onReadyStateChange
prop。它给了我们在满足数据需求时更细粒度的事件控制。
Learn how to use this prop in the Ready State guide.
在接下来继续学习State