添加新技能后,技能列表不会更新

时间:2019-03-12 04:35:49

标签: javascript reactjs graphql react-apollo

在背景部分有一些技巧和经验。单击技能手风琴上的标题后,将弹出带有技能表格的模态,在填写并提交该技能模版后,模态将关闭,技能列表应得到更新,但不会更新。我必须刷新才能看到技能列表中的更改。这是我的工作方式

class Background extends React.PureComponent {
  state = {
    show: false,
    componentName: null,
    activeIndex: 0
  };

  handleModal = (action, componentName) =>
    this.setState(state => ({
      show: action,
      componentName
    }));

  render() {
    const { show, activeIndex, componentName } = this.state;
    return (
      <React.Fragment>
        <ProfileWrapper>
          <Query query={BACKGROUND_QUERY}>
            {({
              data: { experiences, skills, languages, educations } = {},
              loading
            }) => {
              if (loading) {
                return <h1>Loading...</h1>;
              } else {
                return (
                  <Grid columns={2}>
                    <Accordion
                      index={1}
                      onToggle={this.handleToggle}
                      css="max-width: 100%; min-width: 200px;"
                    >
                      <Accordion.Title>
                        <Title>
                            Skills (
                            {`${skills !== undefined && skills.edges.length}`})
                        </Title>
                      </Accordion.Title>
                      <Accordion.Content>
                        <Content>
                          {skills !== undefined && skills.edges.length > 0 && (
                            <span>
                              {skills.edges.map(skill => {
                                return (
                                  <React.Fragment key={skill["node"].id}>
                                    <span key={skill["node"].id}>
                                      <Chip>{skill["node"].title}</Chip>
                                    </span>
                                  </React.Fragment>
                                );
                              })}
                            </span>
                          )}
                        </Content>
                      </Accordion.Content>
                    </Accordion>
                    <Modal
                      position="centerCenter"
                      open={show}
                      onClose={() => this.handleModal(false, null)}
                    >
                      <React.Fragment>
                        {componentName !== null &&
                          componentName === "experiences" && (
                            <Experiences experiences={experiences} />
                          )}
                        {componentName !== null &&
                          componentName === "skills" && (
                            <Skills skills={skills} />
                          )}

                      </React.Fragment>
                    </Modal>
                  </Grid>
                );
              }
            }}
          </Query>
        </ProfileWrapper>
      </React.Fragment>
    );
  }
}

export default Background;


const Skills = ({ handleSubmit, ...props }) => {
  const formSubmit = async (val, mutation) => {
    const {
      data: { skill: response }
    } = await mutation({
      variables: val
    });
    console.log('response', response);
    if (response.success) {
      props.closeModal();
      toast.success("New Skill Added!");
    }
  };
  return (
    <React.Fragment>
      <Mutation mutation={CREATE_SKILL}>
        {mutation => {
          return (
            <form onSubmit={handleSubmit(val => formSubmit(val, mutation))}>
              <Field name="title" label="Title" component={TextField} />
              <Button>
                <Button.Primary>Add Skill</Button.Primary>
                <Button.Secondary>Cancel</Button.Secondary>
              </Button>
            </form>
          );
        }}
      </Mutation>
    </React.Fragment>
  );
};

export default compose(
  reduxForm({
    form: "skillsProfile",
    enableReinitialize: true,
    destroyOnUnmount: false
  })
)(Skills);

为什么在后台组件中完成查询后,乐观的ui更新在这里不起作用?

1 个答案:

答案 0 :(得分:0)

来自docs

  

有时您执行突变时,您的GraphQL服务器和您的Apollo缓存不同步。当您执行的更新取决于缓存中已有的数据时,就会发生这种情况。例如,删除项目并将其添加到列表中。我们需要一种方法来告诉Apollo Client更新项目列表的查询。这就是更新功能的所在!

Apollo无法知道服务器在执行突变(添加一个或多个行,删除一行等)时正在执行哪种操作-它所要做的就是返回的数据通过突变。它可以将此数据与缓存中已存在的对象进行匹配,并相应地更新它们,仅此而已。如果由于突变而缓存了某些字段,并且需要对其进行更新,则需要明确告知Apollo如何执行此操作(请注意,这些字段可能是返回Skills列表的字段,但是从字面上看,它们可能是受突变影响的其他任何字段。

例如,您用于添加技能的update函数看起来像这样:

update={(cache, { data: { addSkill } }) => {
  // assumes addSkill resolves to a single Skill
  const { skills, ...rest } = cache.readQuery({ query: BACKGROUND_QUERY });
  cache.writeQuery({
    query: BACKGROUND_QUERY,
    data: { skills: skills.concat([addSkill]), ...rest },
  });
}}

有关其他示例,请参阅文档。还值得注意的是,在使用readQuerywriteQuery时,如果查询需要任何变量,则需要传递适当的变量。

虽然您 可以 重新获取查询(例如,通过将其指定为refetchQueries的一部分),但对于缓存的简单更新和显然比仅使用update慢,因为它需要再次往返服务器。此外,update甚至可以与optimistic updates to your UI一起使用。