[英]React hooks reset state and fetch data
I'm building an app with React native.我正在用 React Native 构建一个应用程序。 I'm using a
FlatList
with an onRefresh
handler:我使用的是
FlatList
与onRefresh
处理程序:
<FlatList
data={data}
renderItem={renderPost}
keyExtractor={(item, index) => index.toString()}
onEndReached={handleLoadMore}
onEndReachedThreshold={0.5}
ListFooterComponent={renderFooter}
refreshing={isRefreshing}
onRefresh={handleRefresh}>
</FlatList>
Within that onRefresh
handler I reset the data list and fetch new data:在
onRefresh
处理程序中,我重置数据列表并获取新数据:
const handleRefresh = () => {
setData([]);
setIsRefreshing(true);
fetchData();
}
The problem is that data
is never set to []
.问题是
data
从未设置为[]
。 I can read here that it's expected behaviour: useState set method not reflecting change immediately .我可以在这里读到这是预期的行为: useState set 方法不会立即反映更改。
But what would be a better way?但是什么是更好的方法呢? Because when I use,
useEffect
I have the same problem:因为我在使用的时候,
useEffect
也有同样的问题:
useEffect(() => {
setData([])
fetchData();
}, [isRefreshing]);
const handleRefresh = () => {
setIsRefreshing(true);
}
isRefreshing
is never set to true
. isRefreshing
永远不会设置为true
。
What is the best way of tackling this?解决这个问题的最佳方法是什么?
--EDIT - 编辑
fethData
method: fethData
方法:
const fetchData = () => {
const url = 'my-api-url.com?page=' + page;
fetch(url, {
method: 'GET',
}).then((response) => response.json())
.then((json) => {
setData(data.concat(json.data));
setIsLoading(false);
setIsRefreshing(false);
});
}
If you get what I'm trying to do here it might work best for you如果你明白我在这里尝试做的事情,它可能最适合你
// how about isolating all the data fetch related hooks
// fetch will be called anytime your request params updates
// qs is from query string library
const useDataFetch = (url, method, params) => {
const [refreshing, setRefreshing] = useState(false)
const [fetching, setFetching] = useState(false)
const [data, setData] = useState([])
useEffect(() => {
async (() => {
const url = `${url}?${qs.stringify(params)}`
// we set fetching to true while data is still to be fetched
await setFetching(true)
const rawResponse = await fetch(url, {method})
// and set it back to false when done
const newData = rawResponse.json().data
if (refreshing) {
setData(newData)
setRefreshing(false)
} else {
setData([...data, ...newData])
}
setFetching(false)
})()
}, [params])
return {refreshing, setRefreshing, fetching, data}
}
// and use it like this
// only params is outside of useDataFetch because of the feature refreshing
export default myApp = () => {
const [params, setParams] = useState({page: 1})
const {refreshing, setRefreshing, fetching, data} = useDataFetch('my-api-url.com', 'GET', params)
const handleRefresh = async () => {
await setRefreshing(true)
setParams({page: 1})
}
return (
<FlatList
data={data}
renderItem={renderPost}
keyExtractor={(item, index) => index.toString()}
onEndReached={handleLoadMore}
onEndReachedThreshold={0.5}
ListFooterComponent={renderFooter}
refreshing={refreshing}
onRefresh={handleRefresh}>
</FlatList>
)
}
// now things are reuseable and less code from now on
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.