如何在Relay Store中更新Viewer的字段与关联数据?
如何在Relay Store中更新Viewer的用户数据及关联内容
我来帮你搞定这个Relay登录后更新viewer的问题~首先,我们要利用SignInMutation里的updater方法,把登录返回的用户数据替换掉原来的匿名viewer信息,包括关联的notifications数据,具体步骤如下:
1. 确认Mutation包含所需字段
先保证你的SignInMutation已经请求了所有需要更新的内容,包括user的基础信息和notifications关联数据,就像你已经写的那样,要把...NotificationItem_notification片段包含进去,这样Relay才能拿到完整的通知数据用于更新。
2. 在updater函数中操作Store
提交mutation时传入updater函数,里面我们分几步完成更新:
- 获取当前Store里的根级viewer记录
- 从mutation返回的payload里提取登录后的user数据
- 要么更新viewer的单个字段,要么直接替换整个viewer记录(更彻底)
- 更新关联的notifications连接数据
完整代码示例如下:
// 定义SignInMutation const SignInMutation = graphql` mutation SignInMutation($input: SignInInput!) { signIn(input: $input) { user { id name email is_anonymous notifications { edges { node { id ...NotificationItem_notification } } } } } } `; // 提交mutation并处理Store更新 commitMutation(environment, { mutation: SignInMutation, variables: { input: { /* 你的登录参数,比如用户名、密码 */ } }, updater: (store, payload) => { // 获取Store根节点 const rootStore = store.getRoot(); // 获取当前的匿名viewer const currentViewer = rootStore.getLinkedRecord('viewer'); if (!currentViewer) return; // 从返回结果中取出登录后的用户数据 const signedInUser = payload.getLinkedRecord('signIn').getLinkedRecord('user'); if (!signedInUser) return; // 方案一:逐个更新viewer字段 currentViewer.setValue(signedInUser.getValue('name'), 'name'); currentViewer.setValue(signedInUser.getValue('is_anonymous'), 'is_anonymous'); currentViewer.setValue(signedInUser.getValue('email'), 'email'); // 更新关联的notifications连接 const userNotifications = signedInUser.getLinkedRecord('notifications'); if (userNotifications) { currentViewer.setLinkedRecord(userNotifications, 'notifications'); } // 方案二:直接替换整个viewer(更适合身份完全切换的场景) // rootStore.setLinkedRecord(signedInUser, 'viewer'); }, });
关键注意点
- 如果匿名viewer和登录后的user ID不同,方案二直接替换整个viewer会更稳妥,能避免字段更新不彻底的问题,让Relay完全用新用户数据覆盖原有匿名数据。
- 确保你的组件订阅了viewer的相关字段,这样Store更新后组件会自动重新渲染,展示登录后的用户信息和通知。
- 片段
...NotificationItem_notification要包含通知组件需要的所有字段,否则更新后通知可能显示不全。
内容的提问来源于stack exchange,提问作者Erick Arroyo
相关产品推荐
相关产品推荐

