反应挂钩重置状态并获取数据

时间:2020-03-11 15:18:00

标签: javascript reactjs react-native react-hooks use-effect

我正在使用React native构建一个应用程序。我正在将translate()max(obj.value for obj in Dict.values()) 处理程序:

FlatList

在该onRefresh处理程序中,我重置了数据列表并获取了新数据:

 <FlatList 
  data={data} 
  renderItem={renderPost}
  keyExtractor={(item, index) => index.toString()}
  onEndReached={handleLoadMore}
  onEndReachedThreshold={0.5}
  ListFooterComponent={renderFooter}
  refreshing={isRefreshing}
  onRefresh={handleRefresh}>
</FlatList>

问题在于onRefresh从未设置为 const handleRefresh = () => { setData([]); setIsRefreshing(true); fetchData(); } 。我在这里可以看到它的预期行为: useState set method not reflecting change immediately

但是有什么更好的方法?因为当我使用data时,我遇到了同样的问题:

[]

useEffect从未设置为useEffect(() => { setData([]) fetchData(); }, [isRefreshing]); const handleRefresh = () => { setIsRefreshing(true); }

解决这个问题的最佳方法是什么?

-编辑

isRefreshing方法:

true

1 个答案:

答案 0 :(得分:1)

如果您在这里得到了我想要的帮助,那么它可能最适合您

// 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