在 React/React Native 中,如何防止在选项卡更改、表单更改等时对已检索到的图像发出新的网络请求
Posted
技术标签:
【中文标题】在 React/React Native 中,如何防止在选项卡更改、表单更改等时对已检索到的图像发出新的网络请求【英文标题】:How do I prevent new network requests made for already-retrieved images on tab change, form change etc. in React/React Native 【发布时间】:2021-12-08 06:06:31 【问题描述】:当我更改页面上的某些内容(例如检查单选按钮或切换选项卡)时,会从浏览器发送新的网络请求以检索图像。我已经在我制作的几个网站上注意到了这一点,但永远不应该有另一个请求;我不会在前端更改这些值时执行fetch
。我不明白为什么要再次请求图像。
我附上了一个 gif,显示它发生在我使用 React Native 制作的应用程序中,尽管我也在我的 React 项目中看到过它。当我在右侧的 devtools 中切换选项卡和网络调用时,您可以看到图像闪烁,我也担心性能影响。
如何防止这种情况发生?
对于上下文,我的应用中的数据流如下:
-
在
App.tsx
渲染MainStackNavigator
组件。
在MainStackNavigator
调用firebase 以检索数据(包括图像)。将该数据存储在Context
。
在Home.tsx
渲染Tabs
组件,还要创建一个包含标签数据的数组,即要渲染的组件的名称和组件本身。
在选项卡中根据所选选项卡呈现内容。
Home.tsx
export const Home = (): ReactNode =>
const scenes = [
key: "first",
component: EnglishBreakfastHome,
,
key: "second",
component: SecondRoute,
,
];
return (
<View flex=1>
<Tabs scenes=scenes />
</View>
);
;
Tabs.tsx
export const Tabs = ( scenes : TabsProps): ReactNode =>
const renderScenes = useMemo(() =>
scenes.reduce((map, scene) =>
map[scene.key] = scene.component;
return map;
, )
);
const renderScene = SceneMap(renderScenes);
const [index, setIndex] = useState(0);
const [routes] = useState([
key: "first", title: "Breakfast" ,
key: "second", title: "Herbal" ,
]);
const renderTabBar = ( navigationState, position : TabViewProps) =>
const inputRange = navigationState.routes.map((_, i) => i);
return (
<Box flexDirection="row">
navigationState.routes.map((route, i) =>
const opacity = position.interpolate(
inputRange,
outputRange: inputRange.map((inputIndex) =>
inputIndex === i ? 1 : 0.5
),
);
return (
// Tab boxes and styling
);
)
</Box>
);
;
return (
<TabView // using react-native-tab-view
style= flexBasis: 0
navigationState= index, routes
renderScene=renderScene
renderTabBar=renderTabBar
onIndexChange=setIndex
initialLayout= width: layout.width
/>
);
;
【问题讨论】:
【参考方案1】:查看react-native-fast-image 之类的内容。甚至是 react-native 文档中的 recommended。
它处理图像的兑现。来自文档:
const YourImage = () => (
<FastImage
style= width: 200, height: 200
source=
uri: 'https://unsplash.it/400/400?image=1',
headers: Authorization: 'someAuthToken' ,
priority: FastImage.priority.normal,
resizeMode=FastImage.resizeMode.contain
/>
)
【讨论】:
【参考方案2】:这里的问题根本不是图像缓存,而是状态管理。
我调用了一个数据库来检索图像,然后将该图像数组存储在包装整个应用程序的AppContext
中。然后,每次我改变状态时,我都会遇到这个问题,因为应用程序正在重新渲染。我做了两件事来消除这个问题:
将Context
分离到单独的存储中,而不仅仅是使用单个全局状态对象。我创建了一个包含所有图像的 ContentContext
,以便将状态与其他状态更改分开,因此不会触发重新渲染。
我使用了useMemo
,并重新编写了卡片(您可以在图像中看到)以仅在主图像数据数组更改时更改。这意味着,无论其他状态变量如何变化,该组件都不需要重新渲染,直到图像数组发生变化。
这两种解决方案中的任何一种都可以单独使用,但为了安全起见,我同时使用了这两种解决方案。
【讨论】:
以上是关于在 React/React Native 中,如何防止在选项卡更改、表单更改等时对已检索到的图像发出新的网络请求的主要内容,如果未能解决你的问题,请参考以下文章
React / React Native:如何映射数组并在卡片上显示数据
如何制作需要特定导入的混合包 React/React-Native
在 React/React Native 中,如何防止在选项卡更改、表单更改等时对已检索到的图像发出新的网络请求