ReactJS:空组件在再次获取之前获取的旧数据



我正在从我的 React 组件获取远程数据。数据准备就绪后,将呈现子组件。加载数据时,"数据正在加载..."。将显示文本。

当组件由于props更改而第二次呈现时,我将以前的数据设置为null以显示正在加载新数据。

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>
)
}

这种方法的问题是,当组件第二次呈现时,setItems(null);代码不会立即执行(可能是因为useEffect是异步执行的(,并且组件重新渲染 3 次而不是预期的 2 次:

  • 由于道具更改而进行 1-st 重新渲染(但使用旧数据,因为执行setItems(null)太晚了(
  • 最终执行setItems(null)后的第二次重新渲染
  • 获取数据后第三次重新渲染

我明白我的方法有什么问题。但我看不到其他方法。 必须使用钩子。

有什么想法吗?

一个快速的解决方法是将一个关键道具添加到您的列表中:

<List key={page} page={page} />

当页面的值更改时,将卸载 List 组件,并呈现一个新组件。新的将没有任何以前的数据,因此您只会获得 2 个渲染而不是 3 个。

这意味着您不必再将以前的数据设置为null

如果这样做,则需要在调用setItems之前检查组件是否仍挂载在useEffect中,否则您将尝试在未挂载的组件上设置状态。你可以写:

if(setItems) {
setItems(data)
}

不过,更改关键道具有点笨拙,所以我会研究其他方法来解决您的问题。

也许您应该将数据传递到列表中,而不是负责获取数据的列表,并将页面状态和数据都放在父组件中?

不过,就目前而言,使用页面更改密钥应该可以工作。

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

相关内容

  • 没有找到相关文章

最新更新