Mar*_*nho 1 javascript typescript reactjs react-hooks
当加载更多数据并附加到状态时,我遇到了经典的无限滚动问题。
我有一个页面,其中显示了自定义的无限滚动城市列表。
这些城市是从外部库中获取的。
import { City, Country, CitiesQuery } from "an-external-library";
export const CountryComponent: FC<Props> = ({ country: Country }) => {
const [cities, setCities] = useState<City[]>([]);
const [citiesQuery, setCitiesQuery] = useState<CitiesQuery>();
const loadMoreCities = useCallback(() => {
console.log("loadMoreCities", "cities", cities);
citiesQuery
?.load((newCities) => {
console.log("loadMoreCities", "newCities", newCities);
const updatedCities = [...cities, ...newCities];
console.log("loadMoreCities", "updatedCities", updatedCities);
setCities(updatedCities);
})
.then(() => setCitiesQuery(citiesQuery))
.catch(console.error)
}, [cities]); // I've tried adding more dependencies here
useEffect(() => {
const query = country.createCitiesQuery()
query.limit = 3; // example
query
.load(setCities)
.then(() => setCitiesQuery(query)) // so that I can load more from where I left
.catch(console.error)
}, []);
useEffect(() => {
// so that we know what's actually being set
console.log("cities", cities);
}, [cities])
return (
<>
// ...
<CitiesList cities={cities} onScrollBottom={loadMoreCities}/>
</>
)
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,该loadMoreCities函数在更改时似乎没有更新cities,因此 insideloadMoreCities始终cities相同,并且不反映以前的附加。
这是一个运行日志的示例:
// initial render
cities: Array(0) []
// after first useEffect runs
cities: Array(3) ["A", "B", "C"]
// scroll bottom
loadMoreCities, cities: Array(3) ["A", "B", "C"]
loadMoreCities, newCities: Array(3) ["D", "E", "F"]
loadMoreCities, updatedCities: Array(6) ["A", "B", "C", "D", "E", "F"]
cities: Array(6) ["A", "B", "C", "D", "E", "F"]
// scroll bottom again
loadMoreCities, cities: Array(3) ["A", "B", "C"] // <---- this is a problem
loadMoreCities, newCities: Array(3) ["G", "H", "I"]
loadMoreCities, updatedCities: Array(6) ["A", "B", "C", "G", "H", "I"]
cities: Array(6) ["A", "B", "C", "G", "H", "I"] // <---- as consequence, we lost ["D", "E", "F"]
Run Code Online (Sandbox Code Playgroud)
我尝试在 中添加所有可能的依赖项组合useCallback,但似乎没有任何效果。
我确信我错过了一些非常简单的东西,但看不出是什么。
尝试:
.load((newCities) => {
setCities(cities => [...cities, ...newCities]);
})
Run Code Online (Sandbox Code Playgroud)
代替:
.load((newCities) => {
setCities([...cities, ...newCities]);
})
Run Code Online (Sandbox Code Playgroud)
setState可以接受一个值或一个 setter 函数
连续调用一个值将仅导致最后应用的
const [state, setState] = useState([])
setState([...state, 'a']) // current state = []
setState([...state, 'a']) // current state = []
setState([...state, 'c']) // current state = []
// the result will be `['c']`
Run Code Online (Sandbox Code Playgroud)
使用 setter 回调将使 React 记住每个回调,然后使用更新的数据运行每个回调
const [state, setState] = useState([])
setState(state => [...state, 'a']) // current state = []
setState(state => [...state, 'a']) // current state = ['a']
setState(state => [...state, 'c']) // current state = ['a', 'b']
// the result will be `['a', 'b', 'c']`
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1061 次 |
| 最近记录: |