Component not being updated after state is changed in reducer

212 views Asked by At

I would like to display the error to my user. An error is thrown and the error and message are updated in the reducer by the action. But for some reason I can't get the error or message to display for the user. Is there something wrong with the reducer or mapStateToProps? How does the component know the state has been updated? I'm not sure how to update that.....

What am I missing?

reducer:

import {CREATE_VEHICLE,VEHICLE_ERROR, 
VEHICLE_FORM_PAGE_SUBMIT,FETCH_VEHICLES_SUCCESS} from '../actions/vehicles';

const initialState={message: null, error: null, vehicle:{}};

 export default function vehicleReducer(state=initialState, action) {
console.log("in reducer");
switch(action.type){
case CREATE_VEHICLE:
    return [...state, Object.assign({}, action.vehicle, action.message)];
case VEHICLE_ERROR:
    return{
    ...state,
        error: action.error,
        message: action.message
    };
    default:
        return state;
}
}

actions:

export const vehicleError = (error, msg) => {
return{
type: VEHICLE_ERROR,
error:error,
message: msg
}

};

export const createVehicle=(vehicle) =>{
console.log("vehicle: ", vehicle);

return (dispatch) => {
    return axios.post(`http://localhost:9081/api/bmwvehicle/create`, 
vehicle)

    .then((response) =>{
        if (response.ok){
            console.log("success");
             dispatch(createVehicleSuccess(response.data))

        }}, (error) => {
                if (error.response.status == 500){
                dispatch(vehicleError(error.message, "Could not add vehicle, 
please try again."));

            }

        }
    );
};};

component:

class Vehicle extends React.Component{
 constructor(props){
        super(props);
      }


      submitVehicle(input){
        this.props.createVehicle(input);
        }

      render(){
          console.log("the error is: ",this.props.error);
            return(
                    <div>
                        <AddVehicle submitVehicle= 
{this.submitVehicle.bind(this)} /> 
                    </div>

                )
      }
}

      const mapStateToProps=(state, ownProps) => {
          return{
              vehicle: state.vehicle,
              message: state.message,
              items: state.items,
              vehicles: state.vehicles,
              error: state.error
          }
      };

      const mapDispatchToProps=(dispatch)=>{
          return {
              createVehicle: vehicle => 
dispatch(vehicleActions.createVehicle(vehicle))
          }
      };


export default connect(mapStateToProps, mapDispatchToProps)(Vehicle);
1

There are 1 answers

0
Shawn Andrews On

In your CREATE_VEHICLE action, i think you meant to return the state with curly braces instead? {...state, Object.assign({}, action.vehicle, action.message)}

In your mapStateToProps, you attempt to access state.vehicles and state.items, but it does not exist in your default initial state const initialState={message: null, error: null, vehicle:{}}.

To answer your question about how does the component know the (redux) state has been updated, the component knows because you wrapped it in the Redux HoC called connect() which will notify your component via an update anytime the mapped redux state changes. In your case, the component will be updated on changes to the redux store's state.vehicle, state.message, state.items, state.vehicles and state.error.