3

I know there are a lot of same questions posted in this site but none of them links to my issue. This is close to mine but I am not working with DB yet. Just a complete react/redux implementation.

I am implementing redux in my sample project for reactstrap modal and confuses me because one of my reducers not updating the state the first time. Consider my redux setup.

Action

export const showModal = (data) => {
   return {
    type: MODAL_TOOL,
    payload: data
  };
}

Reducer

 const initialState = {
     isOpen: false
 };
 export default function(state=initialState, action) {
    switch(action.type) {
        case MODAL_TOOL:
            console.log(action.payload.isOpen); //logs true
            return {
                 ...state, 
                 isOpen: action.payload.isOpen
            }
        default: 
             return state;
   }
}

Combine Reducer

export default combineReducers({
    modal: modalReducer
});

Component

class TaskModel extends Component {
   state = {
       isOpen: this.props.modal.isOpen
   }
   onCreateTask = () => {
        this.props.showModal({
            isOpen: !this.props.modal.isOpen
        });

        this.setState({
            isOpen: this.props.modal.isOpen
        }); 
   }
   render() { 
       return(
          <Button
               size="sm"
               color="dark"
               style={{marginBottom: '2rem'}}
               onClick={this.onCreateTask}
           >
                Add Task
           </Button>
       )
   }       
}
const mapStateToProps = (state) => ({
     modal: state.modal
});

export default connect(mapStateToProps, { showModal })(TaskModel);

When I click the button Add Task the first time, it will not update the state even the log from reducer showing true. It works the 2nd time and update the redux state. My CRUD for the tasks is working fine with the same redux setup. Did I misunderstand something?

HTTP
  • 1,674
  • 3
  • 17
  • 22
  • How to you know the redux state is not updating the first time?? – pritesh Oct 22 '18 at 05:52
  • Why track whether it's open both in the state and in the store? Also, updating the Redux store, just like `setState()`, is asynchronous. So your `setState()` call which uses the store value `this.props.modal.isOpen` may not be using the correct value, since you call it synchronously after dispatching your action. – Jayce444 Oct 22 '18 at 06:00
  • I wonder how its even updating the second time. `mapStateToProps` and `connect` need to be placed outside of the class. – Fawaz Oct 22 '18 at 06:08
  • @Fawaz, I update the component. – HTTP Oct 22 '18 at 06:13
  • @pritesh, I am logging the state in the reducer so I know when I click the 2nd time it updates the state. – HTTP Oct 22 '18 at 06:13
  • Doesn't matter if you are logging or not. Just keep `isOpen` in either redux or state. Not both places. – Fawaz Oct 22 '18 at 06:16

1 Answers1

3

I recommend To use mapDispatchToProps because this function is made to update redux store. You should call onTodoClick for instance like below in your click handler. And update the redux store. Now you will get 'toggleTodo' in your actions. Next is using mapStateToProps to get redux data. This is how it should work.

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (isOpen) => {
      dispatch(toggleTodo(isOpen))
    }
  }
}

Here is some link to get more about the concept.

https://learn.co/lessons/map-dispatch-to-props-readme

Mustkeem K
  • 8,158
  • 2
  • 32
  • 43