acdlite / redux-router

Redux bindings for React Router – keep your router state inside your Redux store
MIT License
2.3k stars 216 forks source link

pushState to same route with different params #233

Closed jonathanasquier closed 8 years ago

jonathanasquier commented 8 years ago

Hi! I'm doing dispatch(pushState(null, '/user/' + id)); If I do it from any other route that /user/:userId it works fine. When I do it from another /user/:userId url, the navigation bar url updates but the app doesn't.

How can I make it behave like a Link ? (The app updates, and there is no full reload)

Thanks!

mjrussell commented 8 years ago

When you say the app does not update, what exactly do you mean?

Are you using redux's connect function and expecting it to cause a re-render?

Do you see a new redux action being dispatched when you dispatch the pushState on the /user/:userId route?

Also does switching to replaceState behave any differently?

jonathanasquier commented 8 years ago

Hi, and thank you for your answer

yes, I use connect and expecting it to re-render

Let say i'm on '/user/41FPUPaXx' I do dispatch(pushState(null, '/user/E1GWckdNx')) (on click...) the event dispatch is @@reduxReactRouter/routerDidChange, action.payload.param.userId = 'E1GWckdNx', action.payload.location.pathname = '/user/E1GWckdNx'

The url updates to '/user/E1GWckdNx' in the navbar but 'nothing' happens, the app doesn't jump to a new user profile.

The behavior works perfectly from another link (not '/user/:userId')

Switching to replaceState makes a full page refresh and doesn't change the url, not sure I'm using it properly...

Thanks!

mjrussell commented 8 years ago

Is there any chance you can share a gist or snippet of your components from the connected component down to the user profile?

My guess would be that you have either a shouldComponentUpdate check somewhere which is returning false when it should return true, or you are using internal state inside a component and need to do some cleanup in componentWillReceiveProps.

It seems unlikely to me that this is a bug in redux-router, but I could be wrong. One thing you might do is use the react-devtools chrome extension and inspect the props being passed down to the component rendered underneath the router. If it is being passed the correct userId param then its a bug in your component logic.

Scarysize commented 8 years ago

@jonathanasquier Is this still an issue?

jonathanasquier commented 8 years ago

Luckily I had time to work on it this morning, and did this test with both Link from react-router and MenuItem from react-bootstrap (with which happens my bug)

var Stuffs = connect(function(state) {
    return state;
})(React.createClass({
    render() {
        return (<div>Stuffs</div>);
    }
}));

var Stuff = connect(function(state) {
    return state;
})(React.createClass({
    goToStuff : function(stuffId){
        var { dispatch } = this.props;
        return function(){
            dispatch(pushState(null, '/stuff/' + stuffId));
        }
    },
    render() {
        var { router } = this.props;
        return (
            <div>
                <div>Stuff {router.params.stuffId}</div>
                <div><Link to='/stuff/654321'>654321</Link></div>
                <div><Link to='/stuff/987654'>987654</Link></div>
                <div>
                    <ButtonToolbar>
                        <DropdownButton title='dropdown' dropdown id="dropdown">
                            <MenuItem onClick={this.goToStuff(987654)} eventKey="1">
                                987654
                            </MenuItem>
                            <MenuItem onClick={this.goToStuff(654321)} eventKey="2">
                                654321
                            </MenuItem>
                        </DropdownButton>
                    </ButtonToolbar>
                </div>
            </div>
        );
    }
}));

render(
    <div>
        <Provider store={store}>
            <ReduxRouter>
                <Route path="stuffs" component={Stuffs}/>
                <Route path="stuff/:stuffId" component={Stuff}/>
                <Redirect from='*' to='/stuffs'/>
            </ReduxRouter>
        </Provider>
        {debug}
    </div>,
    document.getElementById('root')
);

and (sadly for me) It works perfectly. My bugged project is of course more complex but does the exact same dispatch(pushState(null, '/stuff/' + stuffId));. The url changes, the same actions are dispatched, but the page doesn't refresh.

So Its obviously not an issue with redux-router, but still an issue for me :( I bet I'm alone with it now!

Feel free to close it :)

jonathanasquier commented 8 years ago

I'll stick with a href='stuff/:stuffId that triggers a full page reload for now.

Scarysize commented 8 years ago

Okay, thanks for the quick feedback. Hope you get the problem sorted out!