dataIdFromObject 不更新的 Apollo 规范化

Apollo Normalization with dataIdFromObject not updating

我在发送删除突变后无法让 React+Apollo 更新商店。我正在使用内置了 apollo+react 的 reactQL 样板和一个 express graphQL 服务器(我没有安装 apollo 服务器——我只是使用参考 express-graphQL 包)。我的数据存储在 mongoDB 中,带有 _id,但客户端的实际数据使用 id 作为 id。

apollo客户端是这样定义的:

new ApolloClient(
    Object.assign(
      {
        reduxRootSelector: state => state.apollo,
        dataIdFromObject: o => o.id
      },
      opt
    )
  );

我有一个父组件使用 从 'src/graphql/queries/courses.gql

导入课程
@graphql(courses)
export default class CoursesPage extends Component {
  constructor(props){
    super(props)
    this.handleDelete = this.handleDelete.bind(this);
  }

  handleDelete(event) {
    this.props.mutate({ variables: {id: selectedId}}
              .catch(err => console.log(err))
  }

  render() {
    return (
      { this.props.data.courses.map(course =>
         <CourseDelete selectedId={course.id} key={course.id} />
        })
      }
    )
  }

}

和一个看起来像这样的子组件:

import deleteCoursefrom 'src/graphql/mutations/deleteCourse.gql

@graphql(deleteCourse)
export default class CourseDelete extends Component {
  constructor(props){
    super(props)
    this.handleDelete = this.handleDelete.bind(this);
  }

  handleDelete(event) {
    this.props.mutate({ variables: {id: this.props.selectedId}}
              .catch(err => console.log(err))
  }

  render() {
    return (
      <button onClick={this.handleDelete}>Button</button>
    )
  }

}

其中 deleteCourse.gql:

mutation deleteCourse($id: String!) {
  deleteCourse(id: $id) {
    id
  }
}

我的原始查询在 courses.gql:

query courses {
  courses {
    id
  }
}

Apollo 的dataIdFromObject 用于更新缓存中已有的对象。因此,如果您有一个记录和一个 ID,并且您根据同一个 ID 更改了其他数据,则监听商店的 React 组件可以重新呈现。

由于您的 deleteCourse 变异似乎 return 相同的 ID,它仍然存在于缓存中。您的商店不知道它需要删除 - 它只是用返回的任何数据更新缓存。由于此突变可能 return 是相同的 ID,因此没有任何迹象表明应将其删除。

相反,您需要指定一个 update function(link 转到官方 Apollo 文档)以明确删除底层存储数据。

在我的新 ReactQL user auth example, I do the same thing (see the pertinent LOC here) 中 'manually' 在用户登录后更新商店。

由于组件最初侦听 'blank' 用户,我不能依赖 dataObjectFromId 来使缓存无效,因为我开始时没有用户,因此没有 ID。所以我手动显式覆盖存储状态,这会触发任何监听组件的重新渲染。

我解释的概念是 YouTube 视频中上述用户身份验证的上下文 - 这是相关的部分:https://youtu.be/s1p4R4rzWUs?t=21m12s