Search code examples
javascriptreactjsreduxreact-reduxredux-form

Connected property is updated only once, its not updating for second time


I am using redux-forms to handle all form related things. But both redux-form and connect decorators are not working together well. Connect is updating my showSpinner property once as submission of form changes my redux store. But next time when the redux store is changing, my connected property doesn't update.

Here's the code:

component.js

const formSubmit = (values, dispatch) => {
    dispatch(submitLogin(values));
}

const mapStateToProps = (state, ownProps) => {
  return {
    app: state.app,
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
        mockSubmit: values => {
            dispatch(submitLogin(values));
        }
  }
}

@connect(mapStateToProps, mapDispatchToProps)
@reduxForm({form: 'loginForm', validate, onSubmit: formSubmit})
class Login extends Component {

  constructor(props) {
    super(props);
  }

  render() {
    const fullWidth = true;
        const self = this;
    return (
      <div>
                <p>{self.props.app.showSpinner.toString()}</p>
                <CircularProgress size={80} thickness={5} style={{display: self.props.app.showSpinner ? "block" : "none"}} />
        <form onSubmit={this.props.handleSubmit}>
          <div className="card-box">
            <div className="head">
              <p>Login</p>
            </div>
            <div className="body">
              <Field name="phone" type="text" component="input" label="Mobile Number"/>
            </div>
          </div>
        </form>
        <Terms/>
      </div>
    )
  }

}
export default Login;

action.js

export function submitLogin(data){
  return dispatch => {
    dispatch(fetchLoginApi(data));
    fetchLogin(data) //a helper method to hit login api
      .then(res => {
        dispatch(verifiedUser(res));
      })
      .catch(err => console.log(err))
  }
}

function fetchLoginApi(data) {
  return{
    type: SUBMIT_LOGIN,
    data
  }
}

function verifiedUser(data) {
  return {
    type: VERIFIED_USER,
    data
  }
}

app.js //in combine reducer, I am adding this reducer as app

const initialState = {
  showSpinner: false,
  showAlert: false,
  showConfirm: false,
}

export function app(state = initialState, action) {
  switch(action.type) {

     case SUBMIT_LOGIN:
     return Object.assign(state, {
       showSpinner: true
     });
      break;

    case VERIFIED_USER:
      return Object.assign(state, {
        showSpinner: false
      });
      break;

    default:
      return state;
  }
}

I am using thunk middleware. All the imports are done in right way, there is no syntax mistake and I am using annotations for decorating class with HOCs like connect and reduxForm.


Solution

  • You have incorrectly implemented app reducer. It mutates state object instead of creating a new one.

    Should be

    export function app(state = initialState, action) {
      switch(action.type) {
    
         case SUBMIT_LOGIN:
         return Object.assign({}, state, { // notice new object as the first arg
           showSpinner: true
         });
    
        case VERIFIED_USER:
          return Object.assign({}, state, {
            showSpinner: false
          });
    
        default:
          return state;
      }
    }