React-router-dom与Redux组件不重新渲染问题及解决方案
React Router 路由参数变化时组件不重新渲染的问题解决
我之前也碰到过一模一样的问题!你遇到的情况是:从列表页点击跳转到/post/:id路由时,URL更新了但Post组件没有重新渲染,只有手动在地址栏输入URL才正常工作,甚至用了withRouter也没解决。
问题根源
你当前的routes.js里没有用<Switch>组件包裹路由。React Router在没有Switch的情况下,会匹配所有符合路径规则的Route,而当你从/post/1切换到/post/2时,React会复用已经存在的Post组件实例,不会重新执行componentWillMount(这个生命周期钩子只会在组件挂载时执行一次),所以新的id参数不会触发active_post action去获取新数据。
解决方案步骤
1. 给路由加上<Switch>组件
首先修改你的routes.js,引入Switch并包裹所有Route:
import React, { Component } from "react"; import { BrowserRouter, Route, Switch } from "react-router-dom"; // 引入Switch import Posts from "./components/Posts"; import Post from "./components/Post"; class Routes extends Component { render() { return ( <div> <BrowserRouter> <div> <Switch> {/* 用Switch包裹路由 */} <Route exact path="/" component={Posts} /> <Route path="/post/:id" component={Post} /> </Switch> </div> </BrowserRouter> </div> ); } } export default Routes;
<Switch>会确保只有第一个匹配的路由会被渲染,同时它也会帮助React Router更准确地识别路由参数的变化。
2. 优化组件生命周期(可选但推荐)
另外,componentWillMount已经被React官方废弃了,建议改用componentDidMount,同时加上componentDidUpdate监听路由参数的变化,确保参数更新时重新获取数据:
import React, { Component } from "react"; import { active_post } from "../actions/index"; import { bindActionCreators } from "redux"; import { connect } from "react-redux"; import { Link } from "react-router-dom"; class Post extends Component { componentDidMount() { this.fetchPostData(this.props.match.params.id); } componentDidUpdate(prevProps) { // 当路由id变化时重新获取数据 if (prevProps.match.params.id !== this.props.match.params.id) { this.fetchPostData(this.props.match.params.id); } } fetchPostData(postId) { this.props.active_post(postId); } render() { console.log(this.props.post); return ( <div> <h1>Detail d'un post</h1> <p>{this.props.match.params.id}</p> </div> ); } } function mapStateToProps(state) { return { post: state.activePost }; } function mapDispatchToProps(dispatch) { return bindActionCreators({ active_post }, dispatch); } export default connect(mapStateToProps, mapDispatchToProps)(Post);
这样修改后,不管是从列表页跳转还是手动修改URL,Post组件都会正确响应路由参数的变化,重新获取对应的数据并渲染。
内容的提问来源于stack exchange,提问作者user6275251
相关产品推荐
相关产品推荐

