ReactJS:在再次获取之前清空组件的旧获取数据
我正在从React组件获取远程数据。当数据准备就绪时,将呈现子组件。加载数据时,将显示“数据正在加载…”文本 当由于props更改而第二次呈现组件时,我将先前的数据设置为null,以显示正在加载新数据ReactJS:在再次获取之前清空组件的旧获取数据,reactjs,react-native,fetch,react-hooks,Reactjs,React Native,Fetch,React Hooks,我正在从React组件获取远程数据。当数据准备就绪时,将呈现子组件。加载数据时,将显示“数据正在加载…”文本 当由于props更改而第二次呈现组件时,我将先前的数据设置为null,以显示正在加载新数据 const List = (props) => { const [items, setItems] = useState(null); useEffect(() => { setItems(null); fetch(`http://some_url_to
const List = (props) => {
const [items, setItems] = useState(null);
useEffect(() => {
setItems(null);
fetch(`http://some_url_to_fetch_items.com?PAGE=${props.page}`)
.then((data) => {
setItems(data);
})
}, [props.page]);
if (!items) {
return "Data is loading ......."
}
return (
<ul>
{items.map(item => (
<li>{item}</li>
))}
</ul>
)
}
这种方法的问题是,当第二次呈现组件时,setItemsAll;代码不会立即执行,可能是因为useEffect是异步执行的,并且组件会重新渲染3次,而不是预期的2次:
第一次重新渲染,因为道具更改,但使用旧数据,因为setItemsAll执行得太晚
最终执行SetItemsAll后的第二次重新渲染
获取数据后的第三次重新渲染
我明白我的方法有什么问题。但我看不到另一种方式。
必须使用挂钩
有什么想法吗?一个快速解决方法是在列表中添加一个关键道具:
<List key={page} page={page} />
不过,更改关键道具有点麻烦,所以我会研究其他方法来解决您的问题
也许您应该将数据传递到列表中,而不是让列表负责获取数据,并且让页面状态和数据都在父组件中
不过现在,使用页面更改键应该可以了。您确定要在每次组件重新呈现时重新蚀刻吗?通常,您只需在初始渲染时获取。这就是以状态保存数据的要点。您的数据多久更改一次?如果要在重新渲染时加载新数据,只需在重新渲染时再次设置,无需清除旧数据。此外,您还说要在获取新数据时显示加载。因此,您的组件必须呈现一次以显示加载,并在获取数据后再次呈现。@JMadelaine我不会在每次重新呈现组件时都重新绘制,只有在道具发生变化时才会重新绘制。对于已传递的道具页码,我需要获取相应的项目。想象一下,任何带有分页的列表,用户都可以选择一个页面——这就是我的数据更改的频率。该状态仅用于显示正在加载的数据。。。地位如果我不清除旧数据,我如何在不重新呈现旧项目的情况下显示该状态?@JMadelaine正如我所说,两次呈现“加载”,然后使用数据就可以了。我只需要去掉第一个-对于旧数据,快速修复方法是在列表中添加一个关键道具:。当页面的值更改时,将卸载列表组件,并呈现一个新组件。新的渲染中不会包含任何以前的数据,因此您将只获得2个渲染,而不是3个。这意味着您不必再将以前的数据设置为null。如果执行此操作,则需要在调用setItems之前检查组件是否仍装入useEffect中,否则将尝试在未装入的组件上设置状态。您可以编写ifsetItems{setItemsdata}。
use this method :
useEffect(() => {
fetch(`http://some_url_to_fetch_items.com?PAGE=${props.page}`)
.then((data) => {
setItems(data);
})
}, []);
return (
<ul>
{items? items.map(item => (
<li key={item.id}>{item}</li>
)):"Data is Loading..."}
</ul>
)
use this method :
useEffect(() => {
fetch(`http://some_url_to_fetch_items.com?PAGE=${props.page}`)
.then((data) => {
setItems(data);
})
}, []);
return (
<ul>
{items? items.map(item => (
<li key={item.id}>{item}</li>
)):"Data is Loading..."}
</ul>
)