问题
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