删除突变后不重新获取查询(Apollo Graphql & Nextjs)

Posted

技术标签:

【中文标题】删除突变后不重新获取查询(Apollo Graphql & Nextjs)【英文标题】:After Delete Mutation not Refetching Query (Apollo Graphql & Nextjs) 【发布时间】:2022-01-12 07:30:09 【问题描述】:

我最近将我的 reactjs 代码切换到 nextjs 代码,并且我观察到,当我在 reactjs 代码中时,当我删除数据或执行删除操作时,似乎查询被重新获取并且我得到了数据表中最新或更新的数据,但是当我在 Nextjs 上尝试它时,它不起作用。有没有办法解决这个问题?

请注意我正在使用客户端执行此操作。

代码


Form.js

export default function MainCategoryForm() 
  const [name, setName] = useState("");
  const [file, setFile] = useState();
  const [status, setStatus] = useState("");

  const [createMainCategory,  loading ] = useMutation(
    CREATE_MAINCATEGORY_MUTATION
  );

  async function onSubmit() 
    const res = await createMainCategory(
      variables: 
        name,
        slug: name.toLowerCase(),
        file,
        status,
      ,
      update: (cache,  data:  createMainCategory  ) => 
        const  mainCategories  = cache.readQuery(
          query: FETCH_MAINCATEGORIES_QUERY,
        );
        cache.writeQuery(
          query: FETCH_MAINCATEGORIES_QUERY,
          data:  mainCategories: mainCategories.concat([createMainCategory]) ,
        );
      ,
      refetchQueries: [ query: FETCH_MAINCATEGORIES_QUERY ],
    );
    if (res) 
      toast.success(`Main Category Created`,  autoClose: 2000 );
      setName("");
      setStatus("");
      setFile("");
    
  

  console.log(file);

  return (
    <>
      <Form onSubmit=onSubmit className=loading ? "loading" : "">
        <h2>Create a Main Category:</h2>
        <Form.Field>
          <input
            name="file"
            type="file"
            onChange=(event) => 
              setFile(event.target.files[0]);
            
          />
          <Form.Input
            placeholder="Please Enter Name"
            name="name"
            label="Name: "
            onChange=(event) => 
              setName(event.target.value);
            
            value=name
          />
          <label>Status: </label>
          <select
            name="category"
            className="form-control"
            onChange=(event) => 
              setStatus(event.target.value);
            
            value=status
          >
            <option active="true" hidden>
              Please Enter Status
            </option>

            <option value="Activated">Activated</option>
          </select>
          <br />

          <Button type="submit" color="teal">
            Submit
          </Button>
        </Form.Field>
      </Form>
    </>
  );

如上面这段代码所示,我有这个refetchQueries: [ query: FETCH_MAINCATEGORIES_QUERY ],在添加突变或突变之后,它将重新获取最近数据所需的查询以显示在我的数据表中,我也尝试将它放在 DeleteButton 组件中,但它不工作。

表格

export default function MainCategoryTable(
  mainCategory:  id, name, slug, status, url, createdAt ,
) 
  return (
    <>
      <tr>
        <td>id</td>
        <td>
          <img src=url width=300 />
        </td>
        <td>name</td>
        <td>slug</td>
        <td>status</td>
        <td>dayjs(createdAt).format("h:mm:ss a")</td>
        <td>
          <DeleteButton name=name mainCategoryId=id />
          <Button>
            <Link href=`/mainCategories/$id`>
              <Icon name="edit" style= margin: 0  />
            </Link>
          </Button>
        </td>
      </tr>
    </>
  );

删除按钮组件

export default function DeleteButton( mainCategoryId, callback ) 
  const [confirmOpen, setConfirmOpen] = useState(false);

  const mutation = DELETE_MAINCATEGORY_MUTATION;

  const [deleteMainCategoryOrMutation] = useMutation(mutation, 
    update(proxy) 
      setConfirmOpen(false);
      if (mainCategoryId) 
        const data = proxy.readQuery(
          query: FETCH_MAINCATEGORIES_QUERY,
        );
        data.getMainCategories = data.getMainCategories.filter(
          (ap) => ap.id !== mainCategoryId
        );
        toast.error(`Main Category Deleted`,  autoClose: 2000 );
        proxy.writeQuery( query: FETCH_MAINCATEGORIES_QUERY, data );
      
      if (callback) callback();
    ,
    variables: 
      mainCategoryId,
    ,
  );
  return (
    <>
      <MyPopup content="Delete Main Category">
        <Button
          as="div"
          color="red"
          floated="right"
          onClick=() => setConfirmOpen(true)
        >
          <Icon name="trash" style= margin: 0  />
        </Button>
      </MyPopup>
      <Confirm
        open=confirmOpen
        onCancel=() => setConfirmOpen(false)
        onConfirm=deleteMainCategoryOrMutation
      />
    </>
  );

如果您需要更多代码,例如我的后端或任何文件来找出问题所在,我将始终修改我的文章。如果您需要任何说明或不明白我的意思,请在下方留言。

【问题讨论】:

无类别查询/渲染 - 无需更新...渲染的服务器端 (s-s-r)? 谢谢你的回复,我已经编辑了我的帖子@xadm 我想你会在那里找到你的答案,如果没有请在这里评论:)) 再次感谢 您是否尝试将FETCH_MAINCATEGORIES_QUERYfetchPolicy 查询设置/更改为network-onlycache-and-network 感谢您的回复@Fraction 我前段时间改过,但还是不行 【参考方案1】:

您没有在DELETE_MAINCATEGORY_MUTATION 突变中设置refetchQueries,而是使用update 选项并从缓存中读取查询,但您改变了数据,这不是正确的做法,相反,您应该返回一个新数组,如下所示:

const [deleteMainCategoryOrMutation] = useMutation(mutation, 
    update(proxy) 
      setConfirmOpen(false);
      if (mainCategoryId) 
        const previousData = proxy.readQuery( query: FETCH_MAINCATEGORIES_QUERY );
        const getMainCategories = previousData.getMainCategories.filter(
          (ap) => ap.id !== mainCategoryId
        );
        const data = 
          getMainCategories,
        ;
        toast.error(`Main Category Deleted`,  autoClose: 2000 );
        proxy.writeQuery( query: FETCH_MAINCATEGORIES_QUERY, data );
      
      if (callback) callback();
    ,
    variables: 
      mainCategoryId,
    ,
  );

【讨论】:

以上是关于删除突变后不重新获取查询(Apollo Graphql & Nextjs)的主要内容,如果未能解决你的问题,请参考以下文章

突变后 React Apollo 客户端道具 refetchQueries

如何让 Apollo 客户端重新获取特定查询?

突变后的 Apollo 更新不会触发重新渲染

react-apollo 突变不会重新获取

Vue-apollo 从另一个组件重新获取查询

Apollo 客户端 useQuery 在 useMutation 后不更新数据