javascript - React 路由器、redux、异步 API 请求和旧数据闪存
问题描述
假设我有以下代码(例如):
import React from 'react'
import { Route, Link, Switch } from 'react-router-dom'
import { useSelector, useDispatch } from 'react-redux'
import { useEffect } from 'react'
import { v4 as uuid } from 'uuid'
const Component1 = () => {
const items = useSelector(state => state.app.items);
const dispatch = useDispatch();
useEffect(() => {
const url = makeUrl();
dispatch(fetchItems(url));
}, []);
return (
<p>
Component1 renders!
<ul>
{items.map(item => {
return (
<li key={uuild()}>
<Item1 {...item} />
</li>);
})}
</ul>
</p>
)
}
const Component2 = () => {
const items = useSelector(state => state.app.items);
useEffect(() => {
const url = makeUrl();
dispatch(fetchItems(url));
}, []);
return (
<p>
Component2 renders!
<ul>
{items.map(item => {
return (
<li key={uuild()}>
<Item2 {...item} />
</li>);
})}
</ul>
</p>
)
}
const MainComponent = () => {
return (
<>
<Switch>
<Redirect exact from="/" to="/component1"/>
<Route exact path="/component1" component={Component1} />
<Route exact path="/component2" component={Component2} />
</Switch>
<Link to="/component1">Component1</Link>
<Link to="/component2">Component2</Link>
</>
)
}
有两条路由导航到两个不同的组件,每个组件都有自己独特的 UI/布局、API 请求逻辑等。当我移动到任一路由时,相应的组件就会呈现。
useEffect
一切都按预期工作,但请注意,我在组件第一次使用特殊的第二个参数呈现后发出 API 请求。因此,当 url 更改时,旧组件卸载,另一个安装在他的位置,从而产生新的 API 请求。在每个组件内部,我都依赖于状态,即items
属性。发送 API 请求并在fetchItems
准备好时设置新数据,因此组件重新渲染。
问题是,在另一部分数据准备好之前,我的状态包含一些旧的,现在与上次请求无关的数据。当显示新组件时,它会渲染一次旧数据,然后才会发出新请求。这会导致新布局显示旧数据,这并不总是有意义的。
我可以通过在内部发出请求之前清除所有数据来缓解这个问题fetchItems
。但是,由于反应效果的工作方式,它只会在 url 更改后发生,所以我的组件将使用旧数据呈现,然后才会使用空数据呈现。如果我的布局有点复杂,显示旧数据的新 UI 的闪烁会变得很明显。是否有一种很好且轻松的方式来处理它并使我的组件在功能组件内的新数据可用之前不会重新渲染旧数据?
我知道我可以为状态中的每种类型的数据创建两个单独的字段,但这根本不能解决问题,因为我的组件会从它自己的最后一个请求中呈现相应的数据。
解决方案
推荐阅读
- reactjs - 无法读取不可变记录中的列表条目
- javascript - JS:如何推迟函数的执行
- ios - 初始化节点时找不到值
- java - 用两个数字的特定数字总和排列数字的算法
- apache - 如何防止apache解码url?
- php - 关于 imap 消息的 PHP 通知
- node.js - Firebase admin.database.enableLogging(true)不起作用
- android - 如何在 Geofence android 中添加后台服务
- c# - 在 Windows 上不使用 Visual Studio 开发 c# 需要什么?
- html - 高度随 ::after 和相对定位而变化