react-router-dom route component requires page reload
在调用history.push('/ packages')时,URL已更新,但除非重新加载页面,否则组件不会安装(渲染)。如果我调用createHistory({forceRefresh:true})或手动重新加载页面,则UI会正确呈现。如何配置react-router-dom以加载组件而无需显式重新加载页面或使用forceRefresh?
index.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import React from 'react' import ReactDOM from 'react-dom' import { BrowserRouter } from 'react-router-dom' import store from './store' import {Provider} from 'react-redux' import App from './App' ReactDOM.render( <Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider>, document.getElementById('app') ); |
App.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import React, { Component } from 'react' import { Switch, Route } from 'react-router-dom' import PropTypes from 'prop-types' import { Navbar, PageHeader, Grid, Row, Col } from 'react-bootstrap' import LoginFormContainer from './components/Login/LoginFormContainer' import PackageContainer from './components/Package/PackageContainer' class App extends Component { render() { return ( <Grid> <Navbar> <Navbar.Header> <Navbar.Brand>Mythos</Navbar.Brand> </Navbar.Header> </Navbar> <Row className="content"> <Col xs={12} md={12}> <Switch> <Route path='/packages' render={() => <PackageContainer />} /> <Route exact path='/' render={() => <LoginFormContainer />} /> </Switch> </Col> </Row> </Grid> ) } } export default App |
loginActions.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import * as types from './actionTypes' import LoginApi from '../api/loginApi' import createHistory from 'history/createBrowserHistory' const history = createHistory() export function loginUser(user) { return function(dispatch) { return LoginApi.login(user).then(creds => { dispatch(loginUserSuccess(creds)); }).catch(error => { throw(error); }); } } export function loginUserSuccess(creds) { sessionStorage.setItem('credentials', JSON.stringify(creds.data)) history.push('/packages') return { type: types.LOGIN_USER_SUCCESS, state: creds.data } } |
PackageContainer.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import React, { Component } from 'react' import {connect} from 'react-redux' import PropTypes from 'prop-types' import {loadPackages} from '../../actions/packageActions' import PackageList from './PackageList' import ImmutablePropTypes from 'react-immutable-proptypes' import {Map,fromJS,List} from 'immutable' import {withRouter} from 'react-router-dom' class PackageContainer extends Component { constructor(props, context) { super(props, context); } componentDidMount() { this.props.dispatch(loadPackages()); } render() { return ( {this.props.results ? <PackageList results={this.props.results} /> : No Packages Available} ); } } PackageContainer.propTypes = { results: ImmutablePropTypes.list.isRequired, }; const mapStateToProps = (state, ownProps) => { return { results: !state.getIn(['packages','packages','results']) ? List() : state.getIn(['packages','packages','results']) }; } PackageContainer = withRouter(connect(mapStateToProps)(PackageContainer)) export default PackageContainer |
我认为,这个问题是您正在创建
因此,您应该创建历史记录对象并将其导出到
例如:
index.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import { Router } from 'react-router-dom' import createHistory from 'history/createBrowserHistory' ... export const history = createHistory() ReactDOM.render( <Provider store={store}> <Router history={history}> <App /> </Router> </Provider>, document.getElementById('app') ); |
然后,在
loginActions.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import * as types from './actionTypes' import LoginApi from '../api/loginApi' import { history } from './index' export function loginUser(user) { return function(dispatch) { return LoginApi.login(user).then(creds => { dispatch(loginUserSuccess(creds)); }).catch(error => { throw(error); }); } } export function loginUserSuccess(creds) { sessionStorage.setItem('credentials', JSON.stringify(creds.data)) history.push('/packages') return { type: types.LOGIN_USER_SUCCESS, state: creds.data } } |
希望这会有所帮助。
在App.jsx
中
1 2 3 4 | <Switch> <Route path='/packages' render={(props) => <PackageContainer {...props}/>} /> <Route exact path='/' render={(props) => <LoginFormContainer {...props}/>} /> </Switch> |
现在PackageContainer和LoginFormContainer都可以访问历史记录对象