React Router 4 and props.history.push

北城以北 提交于 2019-12-20 03:15:22

问题


There's something driving me crazy in React, and I need your help. Basically, when the user clicks "My Profile", I want to redirect to the user's profile. To do that, I use the following snippet

viewProfile = () => {
    console.log('My USER ID: ', this.props.userId);
    this.props.history.push(`/profile/${this.props.userId}`);
}

This should work. However, although the URL is changing to the correct URL when 'My Profile' is clicked, the page isn't appearing. It just stays as the old page.

After googling for a while, I know it's something to do with redux ... However, I can't find a solution. (this.props.userId is coming from a Layout component, which is in turn getting it from redux store)

Here's my code:

// React
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
// Redux
import { connect } from 'react-redux';
import * as actions from '../../../store/actions/';
// Containers and Components
   ...// more imports

const styles =  // styles

class NavBar extends Component {

  handleAuthentication = () => {
    if (this.props.isAuthenticated) {
      this.props.history.push('/logout');
    } else {
      this.props.history.push('/login');
    }
  };

  viewProfile = () => {
    console.log('My USER ID: ', this.props.userId);
    this.props.history.push(`/profile/${this.props.userId}`);
  };

  render() {
    let buttons = (
      <Auxillary>
        {this.props.isAuthenticated ? (
          <RaisedButton
            label="MY PROFILE"
            primary={true}
            style={styles.button}
            onClick={this.viewProfile} // THIS IS THE METHOD
          />
        ) : null}
        <RaisedButton
          backgroundColor={grey900}
          label={this.props.isAuthenticated ? 'LOGOUT' : 'LOGIN'}
          labelColor={grey50}
          style={styles.button}
          onClick={this.handleAuthentication}
        />
      </Auxillary>
    );

    let itemSelectField = null;
    if (this.props.location.pathname === '/items') {
      itemSelectField = (
        <ItemSelectField
          onSelectTags={tags => this.props.filterItemsByTagName(tags)}
        />
      );
    }
    let bar = null;
    if (
      this.props.location.pathname !== '/login' &&
      this.props.location.pathname !== '/register'
    ) {
      bar = (
        <AppBar
          style={styles.appBar}
          title={itemSelectField}
          iconElementLeft={
            <img style={styles.logoHeight} src={Logo} alt="logo" />
          }
          iconElementRight={buttons}
        />
      );
    }
    return <Auxillary>{bar}</Auxillary>;
  }
}

const mapDispatchToProps = dispatch => {
  return {
    filterItemsByTagName: selectedTags =>
      dispatch(actions.filterItemsByTagName(selectedTags))
  };
};

export default withRouter(connect(null, mapDispatchToProps)(NavBar));

You can find the entire app here: https://github.com/Aseelaldallal/boomtown/tree/boomtown-backend-comm

I'm going crazy trying to fix this. help.


回答1:


You need to integrate the react-router-redux.

Its look like the updated state is not reflecting in the container as redux do shallow comparison to check whether the component need to be update or not.

import {Router} from 'react-router-dom';
import { ConnectedRouter, routerReducer, routerMiddleware } from 'react-router-redux';
import createHistory from 'history/createBrowserHistory';

const history = createHistory()
const middleware = routerMiddleware(history)


const rootReducer = combineReducers({
    router: routerReducer,
  //other reducers
});

const store = createStore(rootReducer,applyMiddleware(middleware));

<Provider store={store}>
<ConnectedRouter>
 //routes
</ConnectedRouter>
</Provider>

Also,at reducers,add this snippet.

let updatedStore = JSON.parse(JSON.stringify(state));



回答2:


I think has to do with you using <BrowserRouter>. It creates its own history instance, and listens for changes on that. So a different instance will change the url but not update the <BrowserRouter>. Instead you can use ConnectedRouter and pass a history instance as

import createHistory from 'history/createBrowserHistory';
...
const history = createHistory();
...
<ConnectedRouter history={history}>
...
</ConnectedRouter>


来源:https://stackoverflow.com/questions/48799733/react-router-4-and-props-history-push

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!