我要做什么:我有几个类别切换按钮。我只想显示已检查类别的数据。
我的方法:用于显示过滤数据的功能会检查按钮数组,查看被打勾的按钮,然后读取查询的缓存。
const getFilteredData = () => {
try {
const freshFilteredData = []
for (var i = 0; i < chipData.length; i ++){
if (chipData[i].clicked){
const itineraryData = client.readQuery({
query: GET_ITINERARY,
variables: {itineraryId : chipData[i].label}
})
const wantedData = itineraryData.getItinerary.dayPlans;
freshFilteredData.push(wantedData)
}
}
setFilteredData(freshFilteredData)
} catch (err) {
console.log(err)
}
}
但是,仅在触发查询后才能读取缓存。因此,我使用if-else语句来决定何时调用getFilteredData
函数。如果只是选中了按钮,那么我将调用查询(完成后将调用getFilteredData
函数),如果未选中按钮,则将直接调用getFilteredData
。
const toggleClick = clickedChip => () => {
const chipClone = [...chipData];
const objectIndex = chipData.findIndex(
chip => chip.key === clickedChip.key
);
chipClone[objectIndex].clicked = !chipData[objectIndex].clicked;
setChipData(chipClone);
if (chipClone[objectIndex].clicked) {
getItinerary({variables: {itineraryId: clickedChip.label}});
} else {
console.log('fire2')
getFilteredData();
}
};
这是我的懒惰查询:
const [getItinerary] = useLazyQuery(GET_ITINERARY, {
onCompleted(data){
console.log('fired');
getFilteredData()
}
});
我的问题:如果我三次单击相同的按钮。
getFilteredData
函数,因为查询不运行
onCompleted
。而且由于单击它,它也不会执行“ else”语句,因此getFilteredData
根本不会运行)这会破坏过滤效果。
我可以摆脱if-else语句,并在两个位置执行getFilteredData
函数:
const toggleClick = clickedChip => () => {
const chipClone = [...chipData];
const objectIndex = chipData.findIndex(
chip => chip.key === clickedChip.key
);
chipClone[objectIndex].clicked = !chipData[objectIndex].clicked;
setChipData(chipClone);
getItinerary({variables: {itineraryId: clickedChip.label}});
getFilteredData();
};
这将涵盖所有基础,但我想知道是否还有更优雅的方法?
答案 0 :(得分:0)
默认情况下,您错过的事情是阿波罗,所有已发出查询的结果都存储在其本地缓存中,随后对查询的任何调用都会从缓存中获取结果(除非您已更改获取策略)。
我们不是手动检查它是否是首次呼叫,而是将这一责任委托给了阿波罗。
我对流程的建议是
1)维护点击的芯片标签的状态变量
2)在芯片的onClick回调中更改上述标签,这将触发查询
3)让阿波罗决定是第一次呼叫还是随后呼叫
const [chipLabel, setChipLabel] = useState(<Initial label here>) // pass the initial value
//that query expects
// pass the state variable above in the query
const itineraryData = useQuery({
query: GET_ITINERARY,
variables: {itineraryId : chipLabel}
})
// all the toggle button should have a click handler like below
onClick={() =>{//call the setChipLabel}}
打开网络选项卡,多次单击任何过滤器按钮,仅在第一次单击期间会发出n / w呼叫。 Apollo客户端很聪明,可以从缓存中读取数据,如果数据已经可用,则默认情况下,提取策略为“缓存优先”。