首页 文章

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

提问于
浏览
2

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

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

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

我的架构如下所示:

{
    viewer(token:$anAuthToken) {
        actor {
          id,
          email,
          ...
        }
    }
}

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

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>;
        }
      }}
        />
    )
};

而且我收到以下错误 .

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

所以我有几个问题 .

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

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

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

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

1 回答

  • 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')},
                            }
                         }
            `,
        };
    }
    

    这里的查询在命名为“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')},
                            }
                         }
            `,
        };
    }
    

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

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

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

    我们来更新吧 .

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

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

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

    所以让我们更新组件 .

    class UserRegistrationViewer extends React.Component {
    
        render() {
            return <UserRegistrationPage user={this.props.viewer.actor} />
        }
    
    }
    

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

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

    希望这可以帮助别人!

相关问题