1

I'm trying to navigate to the previous screen after a redux action. I'm using react-router with react-router-redux and redux-loop.

Here's the scenario:

  1. On the home screen that there's a list of users /home.
  2. Tap on a user to go to their profile /home/profile/1234.
  3. Edit users name and tap save this.props.dispatch(UserState.updateUser(id, user, history).
  4. Once the user is updated successfully, go back to the home screen /home.

Here's some code:

View:

saveProfile = () => {
  const user = {
    name: this.state.name
  }
  this.props.dispatch(UserState.updateUser(this.state.id, user, this.props.history))
}

Action:

export function updateUser(id, user, history) {
  return {
    type: UPDATE_USER,
    payload: {
      id,
      user,
      history
    }
  }
}

Reducer:

case UPDATE_USER:
  return loop(
    state.updateIn(['users', action.payload.id], user => user.merge(fromJS(action.payload.user))),
    Effects.constant(action.payload.history.goBack())
  )

This results in an error Reducers may not dispatch actions.

On a different project, I've used redux-saga and was able to successfully pass the history object to the saga and push/goBack. There seems to be something going on with trying to pass the history object and calling it within redux-loop

I'm working on a POC for an updated navigation system for an existing production app, so working with redux-loop is required.

Any tips/help would be greatly appreciated. Please let me know if I'm missing any code that would be helpful.

Zach
  • 880
  • 3
  • 12
  • 23
  • 2
    Does it go away with Effects.constant(action.payload.history.goBack()) removed? I'm assuming the internal implementation of that library is causing an action to be dispatched, potentially as a side effect of the rest of your code. My guess. – Bradford Medeiros Apr 20 '18 at 18:48
  • @BradfordMedeiros yes it does. That was my hunch as well. Just not sure what the proper way to handle this would be. – Zach Apr 20 '18 at 19:12

1 Answers1

1

I think @bradford-medeiros is correct about the problem being with

Effects.constant(action.payload.history.goBack())

That's a side effect, so it should not happen in a reducer. You should not need to pass around the history object.

Not sure what version of react-router-redux you have, but there are typically actions exposed by it that can cause the changes you want.

import {goBack} from 'react-router-redux';


//in reducer
return loop(
   state.updateIn(['users', action.payload.id], user => user.merge(fromJS(action.payload.user))),
   Effects.constant(goBack())
);
bdwain
  • 1,665
  • 16
  • 35
  • Thanks for the tip. I tried this and although I no longer get an error, nothing seems to happen. It looks like the redux action is set, but nothing changes on the screen. Any ideas? – Zach Apr 20 '18 at 23:31
  • Here's a public repo with my code, if you have any ideas on what could be wrong. https://github.com/zachrnolan/react-router-navigation-demo – Zach Apr 20 '18 at 23:33
  • you seem to call createHistory twice. The history object you pass to needs to be the same history object you use when creating the store and middleware. That will allow any actions you dispatch to keep your react component tree in sync – bdwain Apr 21 '18 at 00:18
  • that was it! Thank you so much, saved my day. – Zach Apr 21 '18 at 02:59
  • sweet! glad that helped. – bdwain Apr 21 '18 at 03:18
  • Also I just say this as a comment since it might be helpful, but having used redux a good bit on a major project,. I do encourage you to consider whether or not redux is actually beneficial or not to your project. Really consider what benefits it provides, and then what it obscures. I lean towards disliking answers like I'm providing, but this is a huge problem in the modern web world, and is what I view as the main context probably being overlooked – Bradford Medeiros Apr 25 '18 at 16:48