2

I have the route /zone/:id, when clicking from /zone/123 to /zone/789, I can successfully dispatch an action to get the new state, however the component does not render to display the new data.

I tried adding in a key to the <Link/> that is clicked to change routes to trigger an update but that did not work.

Followed the troubleshooting guide for react-redux and think I may be mutating the state in some way?

Maybe I'm trying to change routes in the wrong way?

I hook into the ComponentWillReceiveProps and check to see if the params.id has changed and if it has I issue the fetchZone action to retrieve the new zone.

Zone.js

class Zone extends Component{
  constructor(){
    super()

    this.state = {
      zone: {}
    }
  }

  componentDidMount(){
    this.props.fetchZone(this.props.params.id)
  }

  componentDidUpdate(prevProps){
    if (prevProps.zone !== this.props.zone){
      this.setState({zone: this.props.zone})
    }  
  }

  componentWillReceiveProps(nextProps){
    if(nextProps.params.id !== this.props.params.id){
      this.props.fetchZone(nextProps.params.id)
    }
  }

 render(){
   ...
 }

 function mapStateToProps(state){
  return {
      zone: state.zones.zone,
      coordinates: state.zones.coordinates
    }
}

export default connect(mapStateToProps, {fetchZone, getCoordinates})(Zone)

Using react-logger shows that the state does return the new zone, but does not update the component.

Reducer

case FETCH_ZONE:
  return { ...state, zone: action.payload.data.result}

Root Reducer

const rootReducer = combineReducers({
  zones: ZonesReducer,
  form: formReducer
});

So props and redux state along with component state will update, yet the component does not re-render with new zone data being displayed.

Community
  • 1
  • 1
Ray
  • 21
  • 1
  • 2

2 Answers2

1
import {withRouter} from 'react-router-dom'

and then

withRouter(connect(mapStateToProps, {fetchZone, getCoordinates})(Zone))
John Rotten
  • 73
  • 1
  • 10
0

You should add setState() in componentWillReceiveProps.

componentWillReceiveProps(nextProps){
    if(nextProps.params.id !== this.props.params.id){
      this.props.fetchZone(nextProps.params.id);
      this.setState(...) // setState here
    }
  }

And here is the document.

fumihwh
  • 1,239
  • 7
  • 13
  • Isn't it bad convention to use setState while using Redux? I think Redux should handle all of state. Correct me if I misunderstood. – Kunok Jan 25 '17 at 08:47
  • 1
    @Kunok http://redux.js.org/docs/faq/OrganizingState.html#organizing-state-only-redux-state You could check this FAQ – fumihwh Jan 25 '17 at 11:26
  • Oh I see , that makes sense! – Kunok Jan 25 '17 at 11:28
  • When I `setState` in `componentWillReceiveProps` it still doesn't update the component. I added `if (nextProps.zone !== this.props.zone){ this.setState({ zone: nextProps.zone}) }` – Ray Jan 25 '17 at 17:18