mocheng / react-and-redux

《深入浅出React和Redux》代码

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

react-router4改变了URL,route不匹配新的URL重新渲染组件

MonsterMoriarty opened this issue · comments

如题,我用react-router4做登录的路由,当我登陆成功后,改变store中存储的currentURL,然后Router中监听到store的变化,用this.setState()改变Router的state,用History改变了页面的URL,并试图引起页面组件路由的重新渲染,render确实被调用了,路由却没有渲染新对应URL的组件。

此时如果刷新页面,则会渲染相应的新组件

  • index.js
import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import Routes from './Routes.js';
import store from './Store.js';
import {Provider} from 'react-redux';
import './css/bootstrap.min.css';
import './css/navbar/chartist-custom.css';
import './css/navbar/main.css';
import './css/navbar/font-awesome.min.css';
import './css/navbar/style.css';
import {createBrowserHistory} from 'history'

const history = createBrowserHistory();

ReactDOM.render(<Provider store={store}>
  <Routes history={history} /></Provider>, document.getElementById('root'));
registerServiceWorker();
  • Routes.js
import React, {Component} from 'react';
import {
  Route,
  Switch,
  Link,
  BrowserRouter,
  Router,
  Redirect
} from 'react-router-dom';
import LoginPage from './views/pages/LoginPage.js';
import SuccessPage from './views/pages/SuccessPage.js';
import errorPage from './views/pages/errorPage.js';
import store from './Store.js';

class Routes extends Component {

  constructor(props) {
    super(props);
    this.URLChange = this.URLChange.bind(this);
    this.getOwnState = this.getOwnState.bind(this);

    this.state = this.getOwnState();
  }

  getOwnState() {
    return {
      currentURL: store.getState()["currentURL"]
    };
  }

  URLChange() {
    console.debug(this.getOwnState()["currentURL"]);
    this.props.history.push(this.getOwnState()["currentURL"]);

    //setState是异步的
    let currentURL = this.getOwnState()["currentURL"];
    this.setState(Object.assign({
      currentURL
    }, {currentURL}), () => {
      //回调方法
      console.debug("1:" + this.state.currentURL)
    })

  }

  componentDidMount() {
    store.subscribe(this.URLChange);
  }

  render() {
    alert("render:" + JSON.stringify(this.props.history.location.pathname));
    return (<BrowserRouter >
      <Switch>
        <Route path="/LoginPage" component={LoginPage}/>
        <Route path="/SuccessPage" component={SuccessPage}/>
        <Route path="/errorPage" component={errorPage}/>
        <Route path="/*" component={errorPage}/>
      </Switch>
    </BrowserRouter>);
  }
}

export default Routes;

我在检测生命周期,发现componentWillUpdate和render执行之后,componentDIdUpdate并不执行。
不知道是不是render出错。

  componentWillUpdate() {
    alert("componentWillUpdate");
  }
  componentDIdUpdate() {
    alert("componentDIdUpdate");
  }

而在LoginPage的render和SuccessPage分别插入alert,发现走的是LoginPage的渲染和alert:

  • LoginPage.js
//展示组件
function LoginPage({login}) {
  alert("LoginPage");
  return (<div>
    <Panel style={PanelStyle}>
      <Image src={require('../../img/logo.png')} style={ImageStyle}/>
      <div style={TitleStyle}>公安民意评测系统</div>
      <FormGroup>
        <FormControl type="text" placeholder="账号" onChange={accountChange}/>
      </FormGroup>
      <FormGroup>
        <FormControl type="password" placeholder="密码" onChange={passwordChange}/>
      </FormGroup>
      <br/>
      <Button className="btn-block" bsStyle="primary" onClick={login}>登录</Button>
    </Panel>
  </div>);
}
  • SuccessPage.js
//展示组件
function SuccessPage() {
  alert("SuccessPage");
  return (<div>SuccessPage
  </div>);
}

调试两天了。。。

题主解决了吗

没有把history传到react router里啊。只是放在了你自己封装的路由上了。
好几个月过去了,应该找到原因了吧。😂