Relay抱怨片段变量,但没有片段有变量

Mat*_*son 2 graphql relayjs

我正在学习接力,我让它工作,但有时感觉就像是偶然的:)

我很抱歉,如果我在这里犯了初学者的错误,我已经阅读了手册和所有的例子,但我似乎无法绕过这一切.

无论如何,我现在有以下问题.

我的架构如下所示:

{
    viewer(token:$anAuthToken) {
        actor {
          id,
          email,
          ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所有数据都在{viewer}下访问,后者负责身份验证.演员领域只是其中之一.

Actor是UserType的实例,即当前登录的用户.

我想要一个理智的组件层次结构,其中顶级组件仅将用户作为props(并为其所需的属性提供片段).但据Relay说,我做得不对,而且我不确定我做错了什么.

我的代码看起来像这样(此刻非常混乱,因为我测试了一些东西):

class UserRegistrationPage extends React.Component {

    render() {
        const user = this.props.user;
        return (
            <View>
                <Text>Email: {user.email}</Text>
            </View>
        );
    }

    submit(model) {
        const user = this.props.user;

        this.props.relay.commitUpdate(
            new UpdateUserMutation({
                id: user.id,
                ...model
            }, {
                onSuccess: response => {
                    console.log("SUCCESS!");
                    console.log(response);
                },
                onFailure: () => {
                    console.log("FAIL!");
                }
            }));
    }

}

UserRegistrationPage = Relay.createContainer(UserRegistrationPage, {
    fragments: {
        user: () => Relay.QL`
            fragment on User {
                email
            }
        `,
    },
});

//////////////////////////////

class UserRegistrationViewer extends React.Component {

    render() {
        return <UserRegistrationPage user={this.props.actor} />
    }

}

UserRegistrationViewer = Relay.createContainer(UserRegistrationViewer, {
    fragments: {
        actor: () => Relay.QL`
            fragment on Viewer {
                actor {
                    ${UserRegistrationPage.getFragment('user')},
                }
            }
        `,
    },
});

/////////////////////////////////

class QueryConfig extends Relay.Route {
    static routeName = 'UserRegistrationRoute';
    static prepareParams = routeConfigParamsBuilder;
    static queries = {
        actor: (Component) =>
            Relay.QL`
                     query {
                        viewer(token:$token) {
                            ${Component.getFragment('actor')},
                        }
                     }
        `,
    };
}

export const UserRegistrationPageComponent = (parentProps) => {
    return (
        <Relay.Renderer
            environment={Relay.Store}
            Container={UserRegistrationViewer}
            queryConfig={new QueryConfig()}
            render={({done, error, props, retry, stale}) => {
        if (error) {
          return <View><Text>Error!</Text></View>;
        } else if (props) {
          return <UserRegistrationViewer {...parentProps} {...props} />;
        } else {
          return <View><Text>Loading...</Text></View>;
        }
      }}
        />
    )
};
Run Code Online (Sandbox Code Playgroud)

而且我收到以下错误.

警告:RelayContainer:组件UserRegistrationPage使用与用于获取片段的变量不同的变量进行渲染 user.片段是使用变量获取的(not fetched),但是使用变量进行渲染{}.这可以指示两种可能性之一: - 父级在查询中设置正确的变量UserRegistrationPage.getFragment('user', {...})- 但在渲染组件时没有传递相同的变量.一定要通过将它们作为props传递给组件来告诉组件使用哪些变量: <UserRegistrationPage ... />. - 您故意将虚假数据传递给此组件,在这种情况下忽略此警告.

所以我有几个问题.

1)为什么我会收到该错误,如何解决?我不明白为什么当没有任何片段有任何变量时它会抱怨片段变量.

2)我怎样才能使UserRegistrationPage获得this.props.user?我应该创建一个映射查询响应的组件树层次结构吗?在某些时候我有this.props.actor.user,但我不希望组件知道查询响应结构,只知道它感兴趣的对象.

3)查询的名称是否以某种方式与片段的名称相结合?

任何帮助,改进建议,提示和答案都是非常受欢迎的,我开始在这里撞墙了:)

Mat*_*son 5

我终于理解了之前没有找到的一些细节.我会在这里发布它们,以防它帮助其他任何正在与Relay挣扎的人.

class QueryConfig extends Relay.Route {
    static routeName = 'UserRegistrationRoute';
    static prepareParams = routeConfigParamsBuilder;
    static queries = {
        actor: (Component) =>
            Relay.QL`
                     query {
                        viewer(token:$token) {
                            ${Component.getFragment('actor')},
                        }
                     }
        `,
    };
}
Run Code Online (Sandbox Code Playgroud)

这里的查询在命名为"actor"时会产生误导,因为它不会返回actor.它返回查询的根,即查看者.此外,包含的片段是供观看者而不是演员.

我们来更新吧.

class QueryConfig extends Relay.Route {
    static routeName = 'UserRegistrationRoute';
    static prepareParams = routeConfigParamsBuilder;
    static queries = {
        viewer: (Component) =>
            Relay.QL`
                     query {
                        viewer(token:$token) {
                            ${Component.getFragment('viewer')},
                        }
                     }
        `,
    };
}
Run Code Online (Sandbox Code Playgroud)

完成.让我们看看第一个容器有什么问题.

UserRegistrationViewer = Relay.createContainer(UserRegistrationViewer, {
    fragments: {
        actor: () => Relay.QL`
            fragment on Viewer {
                actor {
                    ${UserRegistrationPage.getFragment('user')},
                }
            }
        `,
    },
});
Run Code Online (Sandbox Code Playgroud)

同样的事情,名字有误导性.此容器不会将actor提供给组件,而是为查看器提供信息.

我们来更新吧.

UserRegistrationViewer = Relay.createContainer(UserRegistrationViewer, {
    fragments: {
        viewer: () => Relay.QL`
            fragment on Viewer {
                actor {
                    ${UserRegistrationPage.getFragment('user')},
                }
            }
        `,
    },
});
Run Code Online (Sandbox Code Playgroud)

因此,此处仅更改了片段的名称.

现在,UserRegistrationViewer组件获得了一个类型为ViewerType的prop"viewer"(由片段指定).我们知道查看器包含"actor",它是UserType的一个实例.UserRegistrationPage需要具有UserType的prop"user",由其片段指定.

所以让我们更新组件.

class UserRegistrationViewer extends React.Component {

    render() {
        return <UserRegistrationPage user={this.props.viewer.actor} />
    }

}
Run Code Online (Sandbox Code Playgroud)

现在我们有一个不了解查询响应层次结构的UI组件,一切正常!

我仍然不确定为什么我得到了这个错误:)

希望这可以帮助别人!