GetFragment from a dynamic component in Relay

My use case is that I have a Node application that consumes data from a CMS, and in this CMS I give users the option to select the React component as β€œLayout”. I would like Relay to be able to get a GraphQL fragment from this dynamically selected component. When the parent Layout component is mounted, it fulfills its request and receives the layout component that it needs and sets the Relay variable - then it needs to get a fragment from this component. Is there any way to do this?

Here is the parent level query:

export default Relay.createContainer(WordpressPage, { initialVariables:{ Component: null, page: null, showPosts: false, limit: 5 }, prepareVariables(prevVars){ return{ ...prevVars, showPosts: true } }, fragments: { viewer: ({Component, showPosts, limit}) => Relay.QL` fragment on User { ${PostList.getFragment("viewer", {limit:limit}).if(showPosts)}, page(post_name:$page){ id, post_title, post_type, post_content, thumbnail, layout{ meta_value } } } `, }, }); 

As you can see, it requests and receives the layout field. When it is mounted, it sets the Component Component variable as a React component. Instead of "PostList.getFragment" I would really like to have a Component.getFragment component.

+5
source share
1 answer

What you need to do is interpolate all possible references to the fragments in the query. Starting with Relay v0.7.1, you can interpolate an array of fragment references into your request:

 const COMPONENTS = [ [PostList, 'showPosts'], [OtherKindOfList, 'showOthers'], /* ... */ ]; static initialVariables = { showPosts: false, showOthers: false, /* ... */ }; fragments: { viewer: variables => Relay.QL` fragment on User { ${COMPONENTS.map(([Component, variableName]) => { const condition = variables[variableName]; return Component .getFragment('viewer', {limit: variables.limit}) .if(condition); })}, # ... `, }, }); 

Warning There is currently a limitation in Relay that requires the interpolated expression to be returned:

  • link to fragment

    ${Foo.getFragment('viewer')}

  • array of fragment references

    ${COMPONENTS.map(c => c.getFragment('viewer'))}

  • conditional function that returns exactly one fragment reference

    ${(route) => COMPONENTS[route].getFragment('viewer')}

The original use case for the poster was for a conditional function that returns an array of links to fragments that is not yet supported. See Comments for more information. See Also facebook / relay / issues / 896

+7
source

Source: https://habr.com/ru/post/1241742/


All Articles