我想做什么:我有几个类别切换按钮。我只想显示已检查类别的数据。
我的方法:用于显示已过滤数据的功能会检查按钮数组,查看被打勾的按钮,然后读取查询的缓存。
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();
};
这将涵盖所有基础,但我想知道是否还有更优雅的方法?
默认情况下,您错过的是阿波罗,所有已发出查询的结果都存储在其本地缓存中,任何随后的查询调用都会从缓存中获取结果(除非您已更改提取策略)。
而不是我们手动检查是否是首次呼叫,而是将这一责任委托给阿波罗。
我对流程的建议是
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客户端很聪明,可以从缓存中读取数据,如果数据已经可用,则默认情况下,提取策略为“缓存优先”。