4

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

在此处输入图像描述

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

...PicturedTypeActivityCard_offer

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


为什么网络调用完成并正确使用分片获取数据,但节点对象始终没有获取到数据?

4

1 回答 1

1

这确实是正确的行为。

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

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

viewer基本上,组件上的道具将具有与片段ActivityTypeLists上请求的查询完全相同的格式,没有来自您在此处引用的其他组件的任何其他片段。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-布尔值

于 2017-08-11T01:02:59.370 回答