1

在我发送删除突变后,我无法让 React+Apollo 更新商店。我正在使用内置 apollo+react 和 express graphQL 服务器的 reactQL 样板(我没有安装 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
  }
}

我的原始查询在 course.gql 中:

query courses {
  courses {
    id
  }
}
4

1 回答 1

2

ApollodataIdFromObject用于更新缓存中已经存在的对象。因此,如果您有一条记录和一个 ID,并且您根据同一 ID 更改其他数据,则侦听存储的 React 组件可以重新渲染。

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

相反,您需要指定一个更新函数(链接转到官方 Apollo 文档)来显式删除底层存储数据。

在我的新ReactQL 用户身份验证示例中,我执行相同的操作(请参阅此处的相关 LOC)以在用户登录后“手动”更新商店。

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

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

于 2017-08-27T07:33:32.567 回答