Relay Modern 节点不包含片段属性

Posted

技术标签:

【中文标题】Relay Modern 节点不包含片段属性【英文标题】:Relay Modern node does not contain fragment properties 【发布时间】:2017-12-23 14:54:28 【问题描述】:

我的 React 项目中有以下设置:

export default class OverviewScreen extends React.Component<any, any> 

public render() 

    return (
        <QueryRenderer
            environment=environment
            query=OverviewScreenQuery
            render=this.queryRender/>
    );


protected queryRender(error, props): JSX.Element 

    if (error) 
        return <div>error.message</div>;
     else if (props) 
        return (
            <div>
                <div>
                    <ActivityOfferList viewer=props.viewer title="Titel"/>
                    <ActivityTypeListsFragment viewer=props.viewer/>
                </div>
            </div>
        );
    
    return <div>Loading...</div>;



const OverviewScreenQuery = graphql`
query OverviewScreenQuery 
    viewer 
        ...HorizontalOfferList_viewer
        ...ActivityTypeLists_viewer
    
`;

class ActivityTypeLists extends React.Component<IHorizontalOfferListProps, any> 

public render() 

    return (
        <div>
        this.props.viewer.allActivityTypes.edges.map((typeEdge) => 
            let typeNode = typeEdge.node;
            return this.getCardListForActivityType(typeNode);
        )
        </div>
    );


private getCardListForActivityType(typeNode: any) 
    console.log(typeNode);

    return (
        <CardList key=typeNode.__id title=typeNode.title>
            typeNode.activities.edges.map((node) => 
                return (
                    <RelayPicturedTypeActivityCard key=node.__id offer=node activityType=typeNode/>
                );
            )
        </CardList>
    );



export const ActivityTypeListsFragment = createFragmentContainer(ActivityTypeLists, graphql`
fragment ActivityTypeLists_viewer on Viewer 
    allActivityTypes(first: 5) 
        edges 
            node 
                ...PicturedTypeActivityCard_offer
            
        
    

`);

export class PicturedTypeActivityCard extends React.Component<any, any> 

    public render() 
        return (
            <PicturedCard title=this.props.offer.title subtitle=this.props.activityType.title width=3/>
        );
    


export const RelayPicturedTypeActivityCard = createFragmentContainer(PicturedTypeActivityCard, graphql`
    fragment PicturedTypeActivityCard_offer on ActivityType 
        title
        activities(first: 4) 
            edges 
            node 
                id
                title
            
        
    
    
`);

哪个应该起作用,并从 graphcool 中继端点给我正确的结果。

对中继端点的网络调用确实正确,我从我的端点接收到所有 ActivityType 及其活动和标题。

但不知何故,在函数 getCardListForActivityType() 中,typeNode 只包含节点的 __id 作为数据,根本没有标题:

如果我直接插入标题和活动而不是使用

...PicturedTypeActivityCard_offer

然后数据也会正确传递。因此,必须关闭 Fragment 的某些内容。


为什么网络调用完成并正确使用了fragment来获取数据,但是node对象却始终没有获取到获取到的数据?

【问题讨论】:

【参考方案1】:

这确实是正确的行为。

您的组件必须单独指定其所有自己的数据依赖项,Relay 只会将其请求的数据传递给组件。由于您的组件不询问任何数据,因此它接收的是一个空对象。

你看到的 __id 是 Relay 内部使用的,你不应该依赖它(这就是为什么它有 __ 前缀)。

基本上,ActivityTypeLists 组件上的 prop viewerActivityTypeLists_viewer 片段上请求的查询具有完全相同的格式,没有来自您引用的其他组件的任何其他片段在那里。

这称为数据屏蔽,请参阅以下链接:

https://facebook.github.io/relay/docs/en/thinking-in-relay.html#data-masking https://facebook.github.io/relay/docs/en/graphql-in-relay.html#relaymask-boolean

【讨论】:

以上是关于Relay Modern 节点不包含片段属性的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 Relay Modern v6 / 实验中的嵌套路由

Relay Modern-React Native 集成的资源

如何处理 Relay Modern 上的突变错误?

如何在 TypeScript 中使用 Relay Modern(babel-plugin-relay 和 relay-compiler)?

中继现代片段错误(期望对象包含数据....)

如何在 Relay Modern 中取消订阅