graphql – Relay Modern节点不包含片段属性

我的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中继端点给我正确的结果.

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

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

《graphql – Relay Modern节点不包含片段属性》

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

...PicturedTypeActivityCard_offer

然后数据也正确传递下来.所以片段的东西必须关闭.

为什么网络调用完成并正确使用片段来获取数据,但节点对象永远不会获取获取的数据?

最佳答案 这确实是正确的行为.

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

您看到的__id是由Relay内部使用的,您不应该依赖它(这就是它具有__前缀的原因).

基本上,ActivityTypeLists组件上的prop查看器将具有与ActivityTypeLists_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

点赞