在背景部分有一些技巧和经验。单击技能手风琴上的标题后,将弹出带有技能表格的模态,在填写并提交该技能模版后,模态将关闭,技能列表应得到更新,但不会更新。我必须刷新才能看到技能列表中的更改。这是我的工作方式
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更新在这里不起作用?
答案 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 },
});
}}
有关其他示例,请参阅文档。还值得注意的是,在使用readQuery
或writeQuery
时,如果查询需要任何变量,则需要传递适当的变量。
虽然您 可以 重新获取查询(例如,通过将其指定为refetchQueries
的一部分),但对于缓存的简单更新和显然比仅使用update
慢,因为它需要再次往返服务器。此外,update
甚至可以与optimistic updates to your UI一起使用。