删除突变后不重新获取查询(Apollo Graphql 和 Nextjs)
After Delete Mutation not Refetching Query (Apollo Graphql & Nextjs)
我最近将我的 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 组件,但它不起作用。
Table
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>
</>
);
}
DeleteButton 组件
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}
/>
</>
);
}
如果您需要任何更多代码(例如我的后端或任何文件)来找出问题所在,我会随时修改我的文章。如果您需要任何说明或不明白我的意思,请在下方留言。
您没有设置 refetchQueries
in the DELETE_MAINCATEGORY_MUTATION
mutation, instead you used the update
选项并从缓存中读取查询,但您改变了数据,这不是正确的做法,您应该 return 一个新的数组如下:
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,
},
});
我最近将我的 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 组件,但它不起作用。
Table
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>
</>
);
}
DeleteButton 组件
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}
/>
</>
);
}
如果您需要任何更多代码(例如我的后端或任何文件)来找出问题所在,我会随时修改我的文章。如果您需要任何说明或不明白我的意思,请在下方留言。
您没有设置 refetchQueries
in the DELETE_MAINCATEGORY_MUTATION
mutation, instead you used the update
选项并从缓存中读取查询,但您改变了数据,这不是正确的做法,您应该 return 一个新的数组如下:
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,
},
});