react监听URL的正确方式

1、原生js硬刚

componentDidMount(){
  window.addEventListener('hashchange', this.routerEvent);
}
componentWillUnmount(){
  window.removeEventListener('hashchange',this.routerEvent);
}

routerEvent = (e)=>{
  // e.target.location.hash.replace("#","")
  // 去掉#就能获取即将跳转的那个路由的url了
}
Tips:addEventListener之后一定要remove,否则跳转路由后,原有的事件又没消除,
会导致注册了越来越多的事件;
另外,removeEventListener的第二个参数指向的函数必须要跟addEventListener传入的函数是同一个函数(这点非常容易错)

这种方式还有种缺点,它只监听到了hash的变化,
而如果是#aaa?page=1跳到了#aaa?page=2,监听不到;

vi设计http://www.maiqicn.com 办公资源网站大全https://www.wode007.com

2、react router自带的history.listen

componentDidMount(){
  this.props.history.listen(route => { 
    console.log(route); // 这个route里面有当前路由的各个参数信息
  });
}

但是,发现,这个history.listen,在组件销毁的时候并不会销毁,事件仍然存在。
如果多次进入同一个路由,这个componentDidMount重复触发,listen重复绑定,跟addEventListener差不多了,
而也没有找到removeEventListener方法。。。
打印一下this.props.history

console.log(this.props.history)

我们可以看到,有listen方法,但是却没有找到解绑的方法;
通过百度没有找到方法,文档里面也没写怎么解绑,
一筹莫展之际,那只能用最后一个方法:翻源码。

说干就干,找到了/react-router/cjs/react-router.js

到这里我们可以推测,
this.props.history.listen()这个函数执行之后,返回值为一个unlisten函数,
unlisten就是listen的解绑函数!
于是代码变成了这样

let UNLISTEN;
class Client extends React.Component {
  ...,
  componentDidMount(){
    // UNLISTEN变量用来接收解绑函数
    UNLISTEN = this.props.history.listen(route => { 
      console.log(route); 
    });
  }
  componentWillUnmount(){
    UNLISTEN && UNLISTEN(); // 执行解绑
  }
}
posted @ 2020-10-03 17:40  笑人  阅读(5969)  评论(1编辑  收藏  举报