【React】简易KeepAlive的探索

前言

  • react官方是没给像vue那种keep-alive功能的,网上有些大佬写了些库,里面涉及的东西有点多。我感觉这玩意也可以自己搞个简陋版本,满足自己需要就行。

原理

  • react-router在对路由匹配时,不匹配的就直接卸载了。所以为了成为常驻组件,就不能让Route来进行匹配渲染。
  • 那么就解决了卸载问题,但又出现3个问题:
  • 一、如何控制组件显示与消失?
  • 二、如何匹配路由?
  • 三、如何解决传值刷新?
  • 对于第一个问题,就是你可以进行display的动态切换来进行渲染。并且这样的切换,子组件不会卸载。
  • 对于第二个问题,一般来说,我们都会使用connected-react-router的中间件,将history传给它,作为store的状态,这样就可以通过store很方便的取到当前匹配的路径,然后对路径进行判断就可以了。
  • 对于第三个问题,其实正常来说,只要有值改变,我们做的keepAlive组件加上里面的子组件全都会刷新,因为使用store一般都会结合connect,当store里面状态发生改变,connect的组件所收到的props就会发生改变,而组件的props改变,会导致组件的刷新。但它确实不会卸载。我们可以通过useEffect加上一个空数组依赖来测试它。
  • 当然,为了优化传值,我们可能有必要在KeepAlive组件里对每个子组件需要什么参数进行整理。

代码

  • 我通过useEffect加空数组的方法看是否卸载。
function  KeepAlive(props:Props) {
    console.log(props)
    useEffect(()=>{
        console.log('我执行了KeepAlive')
    },[])
    useMemo(()=>({}),[props.cart])
    return(
        <>
        <div style={{display:props.router.location.pathname=='/cart'?'block':'none'}}>
        cart
       <KKK cart ={props.cart}></KKK>
        </div>
          <div style={{display:props.router.location.pathname=='/profile'?'block':'none'}}>
          profile
          </div>
        </>
    )
}
const mapStateToProps=(state: CombinedState):CombinedState=>(state)

export default connect(mapStateToProps)(KeepAlive)

function Subcop(params:{cart:CartState}) {
    console.log('xuanr')
    console.log(params.cart)
    useEffect(()=>{
        console.log('我执行了Subcop')
    },[])
    return(
           <div >xxxxxxxxx</div>
    )
}
let KKK = React.memo(Subcop)
  • 我顺便试了下,子组件用React.lazy进行懒加载代码分割也是完全ok,只有第一次出现的时候network会飘来脚本,然后就变成常驻组件。
发布了163 篇原创文章 · 获赞 9 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/yehuozhili/article/details/104766091