Relay Modern节点不包含片段属性

时间:2017-07-18 15:59:02

标签: graphql relayjs graphcool relaymodern

我的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作为数据而根本没有标题:

enter image description here

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

...PicturedTypeActivityCard_offer

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

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

1 个答案:

答案 0 :(得分:1)

这确实是正确的行为。

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

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

基本上,viewer组件上的道具ActivityTypeListsActivityTypeLists_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