react缓存问题

本文介绍了一种常见的React项目中遇到的问题——浏览器缓存导致的新版本部署后页面未更新,并提供了解决方案,即通过在URL后添加hash值如时间戳或随机数的方式,确保浏览器每次都能获取到最新资源。

问题描述:

我们公司自己的react项目,先打包部署v1.1版本,一切正常。

v1.2版本做了很多页面和功能的修改和新增,但是打包部署之后,发现有些界面还是保持了v1.1的状态,比如有些新增按钮没有显示出来等等。需要手动清空浏览器缓存之后才会更新成新页面。

原因:

浏览器在访问相同的url的时候,会根据一些头信息来判断是否重新渲染和向服务器请求资源,也就是说,如果url是相同的,浏览器就有可能偷懒直接从缓存里面加载了旧的资源。

解决:

在页面url后面加hash,可以是时间戳或者随机数,这样每次url都不同,浏览器就不会偷懒了,每次都向服务器取最新的资源,也就解决了react的大坑---浏览器缓存问题。

### React 中实现组件缓存(Keep-Alive 功能) 在 React 中实现类似 Vue 的 `keep-alive` 功能,可以通过以下几种方式完成。以下是详细说明和代码示例: #### 1. 使用第三方库 `react-activation` `react-activation` 是一个专门为 React 设计的库,用于实现页面状态缓存功能。它通过将子组件渲染到一个不会被卸载的容器中,避免组件的重新挂载和卸载[^3]。 ```javascript import React from "react"; import Activation from "react-activation"; function CachedComponent() { const [state, setState] = React.useState(0); return ( <div> <p>当前计数: {state}</p> <button onClick={() => setState(state + 1)}>增加</button> </div> ); } function App() { const [show, setShow] = React.useState(true); return ( <div> <button onClick={() => setShow(!show)}>切换组件</button> {show && ( <Activation> <CachedComponent /> </Activation> )} </div> ); } export default App; ``` 上述代码展示了如何使用 `react-activation` 来缓存组件状态,即使组件被隐藏,其状态仍然保持不变[^3]。 #### 2. 自定义实现 Keep-Alive 功能 如果不希望依赖第三方库,可以手动实现类似功能。通过维护一个映射表来存储组件的状态,并在需要时重新加载组件。以下是一个简单的实现: ```javascript import React, { useState, useEffect, useRef } from "react"; const cacheMap = new Map(); function KeepAlive({ children }) { const cacheKey = JSON.stringify(children.props); const ref = useRef(null); useEffect(() => { if (!cacheMap.has(cacheKey)) { cacheMap.set(cacheKey, React.cloneElement(children)); } ref.current = cacheMap.get(cacheKey); }, [cacheKey, children]); return ref.current || null; } function CachedComponent() { const [state, setState] = useState(0); return ( <div> <p>当前计数: {state}</p> <button onClick={() => setState(state + 1)}>增加</button> </div> ); } function App() { const [show, setShow] = useState(true); return ( <div> <button onClick={() => setShow(!show)}>切换组件</button> {show && <KeepAlive><CachedComponent /></KeepAlive>} </div> ); } export default App; ``` 此方法通过 `useEffect` 和 `useRef` 创建了一个全局缓存机制,确保组件的状态在隐藏后仍然保留[^3]。 #### 3. 结合 `react-router-dom` 实现 Keep-Alive 在 React Router 中,可以通过自定义封装组件来实现类似功能。以下是一个结合 `react-router-dom` 的实现示例[^4]: ```javascript import React from "react"; import { Route, RouteChildrenProps, RouteProps } from "react-router-dom"; type Props = RouteProps; export default function KeepAlive({ path, children, ...rest }: Props) { const child = (props: RouteChildrenProps) => { return ( <div className="keep-alive" style={{ display: props.match ? "block" : "none" }}> {children} </div> ); }; return <Route path={path} {...rest} children={child} />; } ``` 在此实现中,通过设置 `display: none` 来隐藏组件而不是卸载它,从而保留组件的状态。 #### 4. 注意事项 - **React.StrictMode**:如果使用了 `<React.StrictMode />`,可能会导致某些副作用被调用两次,影响状态缓存的效果。因此建议在开发阶段移除 `<React.StrictMode />`[^1]。 - **ReactDOM.render**:在 React 18+ 中,推荐使用 `ReactDOM.createRoot`,但为了兼容状态缓存,可以继续使用 `ReactDOM.render`。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值