React如何让Component检测路由变化

时间:2017-07-21 18:09:25

标签: javascript reactjs react-router react-router-dom

我有3条路由呈现相同的组件<MainContainer/>,我希望状态根据位置在这些组件内部进行更改。

路线:

import React from 'react'
import { browserHistory, HashRouter, Route, Switch } from 'react-router-dom'

import { MainContainer } from '../containers'
import { LoginContainer } from '../containers'

const Routes = () => {
  return (
    <HashRouter history={ browserHistory }>
      <Switch>
        <Route exact={ true } path="/" component={ LoginContainer }/>
        <Route exact={ true } path="/dashboard" component={ MainContainer }/>
        <Route exact={ true } path="/dashboard/services" component={ MainContainer }/>
        <Route exact={ true } path="/dashboard/users" component={ MainContainer }/>
      </Switch>
    </HashRouter>
  );
}

export default Routes

问题是componentDidMount只触发一次,并且在路径改变时不再触发:

enter image description here

如何使用hashRouter在React中实现检测路由状态?

边栏

import React from 'react'
import { withRouter } from 'react-router-dom'

class Sidebar extends React.Component {

  constructor(props) {
        super(props);
        this.state = {}
    this.navigate = this.navigate.bind(this);
    }

  navigate(path) {
    this.props.history.push(`/dashboard/${path}`);
  }

  render () {
    return (
      <aside className="sidebar">
        <div>
          <h1>Main</h1>
          <ul>
            <li onClick={ () => this.navigate('services')}>Services</li>
            <li onClick={ () => this.navigate('users')}>Users</li>
          </ul>
        </div>
      </aside>
    )
  }
}

export default withRouter(Sidebar)

mainContainer上

import React, { Component } from 'react'
import { connect } from 'react-redux'
import store from '../../store'
import * as firebase from 'firebase'

// Components
import { Sidebar } from '../../components'
import { Header } from '../../components'

// Containers
import UserListContainer from '../Users/UserListContainer'
import Body from './Body'

// Actions
import { addCurrentUser, searchUser, usersService, servicesService } from '../../actions'

export class Main extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        firebase.auth().onAuthStateChanged((user) => {
      this.checkAuth();
    });
    }

    checkAuth() {
        const user = firebase.auth().currentUser;
        this.props.addCurrentUser(user.email);
    }

    render() {
        return (
            <main>
                <Header currentUser={ this.props.currentUser }/>
                <section className="main-body">
                    <Sidebar />
                    <Body service={this.props.service}/>
                </section>
            </main>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        service: state.globalReducer.service,
        currentUser: state.globalReducer.currentUser
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        searchUser: (user) => { dispatch(searchUser(user)) },
        addCurrentUser: (user) => { dispatch(addCurrentUser(user)) },
        usersService: () => { dispatch(usersService()) },
        servicesService: () => { dispatch(servicesService()) }
    }
}

const MainContainer = Main;
export default connect(mapStateToProps, mapDispatchToProps)(MainContainer)

1 个答案:

答案 0 :(得分:1)

如果您希望在包含withRouter()的组件中获取当前路径,可以使用location提供给组件的withRouter()道具。

props.location.pathname可能就是您对此感兴趣的内容。

编辑:

好的,所以您的<MainContainer />不知道位置。它没有包含withRouter()。您的<Sidebar />是,但我看不到您在路线更改时使用该信息做了什么。

编辑#2:

一旦您的组件可识别位置,您就可以添加componentWillReceiveProps生命周期方法,并确保您在组件中获得这些属性。您可以在组件中的任何位置使用这些属性。

componentWillReceiveProps( nextProps ) {
    const { location, history, match } = this.props;

    console.log( location );
    console.log( history );
    console.log( match );
}