我试图在按钮单击时从react组件内的api加载更多数据。该数据应与已经加载的数据合并。加载时,我想显示一个微调器。我正在使用axios并响应钩子组件。
我的代码:
const App = props => {
const [data, setData] = useState({ ... });
// ...
function handleLoadMore(uri) {
setData({...data, isLoadingMore: true})
axios
.get(uri)
.then(response => {
setData({
...data,
items: [...data.items, response.data.items]
})
})
.catch(error => {
setData({
...data,
error: 'An error occured'
})
})
.finally(() => {
setData({
...data,
isLoadingMore: false
})
})
}
我希望这会首先显示微调器,加载新数据,将其与现有数据合并,并显示新的项目列表,但新数据不会合并。 ajax调用返回正确的结果,因此没有问题。我期望的是,如果我删除.finally(..)
,一切都会按预期进行,甚至微调框也会消失。
然后的问题是,setData如何更新Promise中的状态?在我看来,根本不清除.finally(..)
是因为isLoadingMore
从未在代码中设置为false,但无论如何它都会更新为false
答案 0 :(得分:3)
很难说,因为代码不完整,但是我看到两个问题(假设丢失的]
只是问题中的错字):
response.data.items
通话中分散setData
。所以(请参阅评论):
click
但是,如果您使用的是这样的组合状态,则我会将const App = props => {
const [data, setData] = useState({ ... });
// ...
function handleLoadMore(uri) {
// *** Use callback
setData(current => ({...current, isLoadingMore: true}));
axios
.get(uri)
.then(response => {
// *** Use callback, spread response.data.items
setData(current => ({
...current,
items: [...current.items, ...response.data.items]
}));
})
.catch(error => {
// *** Use callback
setData(current => ({...current, error: 'An error occured'}));
})
.finally(() => {
// *** Use callback
setData(current => ({...current, isLoadingMore: false}));
});
}
}
的清除与上面的内容结合在一起。
isLoadingMore
但是:您应将separate useState
calls用于不同的状态项。
const App = props => {
const [data, setData] = useState({ ... });
// ...
function handleLoadMore(uri) {
setData(current => ({...current, isLoadingMore: true}));
axios
.get(uri)
.then(response => {
setData(current => ({
...current,
items: [...current.items, ...response.data.items],
isLoadingMore: false // ***
}));
})
.catch(error => {
setData(current => ({
...current,
error: 'An error occured',
isLoadingMore: false // ***
}));
});
}
}
请注意,这如何使更新更加离散,从而减少工作量(不会不断重新散布所有状态项)。