React 如何让 Component 检测路由变化

React How to get Component to detect route change

我有 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 只触发一次,并且在更改路径时不会再次触发:

如何使用 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)

主容器

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)

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

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 );
}