How can i get the new state from the mapped props after dispatching an action

63 views Asked by At

Hello guys ,

I'm just getting started with react Redux and I'm working on a simple crud app.

I'm struggling with a problem of getting the current state of the store by a mapped props in component mapStateToProps .

In the code bellow i have an action creator handling post request with three stages

  • Post Request
  • Post Request Success
  • Post Request Failed
const postClientRequest = (client) => dispatch => {
    dispatch({
        type: clientConstant.POST_CLIENTS.REQUEST,
    })
    return axios.post('http://localhost:5000/client', client)
}

const postClientSuccess = (client) => dispatch => {
    return dispatch({
        type: clientConstant.POST_CLIENTS.SUCCESS,
        payload: client
    })
}

const postClientFailure = (error) => dispatch => {
    return dispatch({
        type: clientConstant.POST_CLIENTS.FAILURE,
        payload: error
    })
}

// action creator contains all the actions for post request
export const postClient = client => dispatch => {

    return dispatch(postClientRequest(client)).then(res => {
        const client = res.data;
        dispatch(postClientSuccess(client));
    }).catch(err => {
        dispatch(postClientFailure(err.message))
    })
}

when I dispatch the action in my index.js file

const client ={
    "firstName":"adam",
    "lastName":"ben",
    "email":"[email protected]",
    "phone":"7939909838720"
  };

store.dispatch(postClient(client)).then(()=>{
    console.log('Get State : ',store.getState())
})

It works fine and i can get the current state of the store immediately.

Screenshot 1 screenshot image

but when i dispatch the action in a component (App.js)

const client ={
    "firstName":"adam",
    "lastName":"ben",
    "email":"[email protected]",
    "phone":"7939909838720"
  };
  const dispatch =useDispatch();

  const ClickBtn=()=>{
    console.log('before Dispatching:',state)
    dispatch(postClient(client)).then(()=>{
      console.log('after Dispatching:',state)
    });
  }

A get a previous action state values (empty array of clients).

Screenshot 2 screenshot image

But when i pass the store to App.js and i console out the store.state i get the lastess state of the store .

 const ClickBtn=()=>{
    console.log('get State from component before Dispatching :',store.getStat())
    console.log('before Dispatching:',state)
    dispatch(postClient(client)).then(()=>{
      console.log('after Dispatching:',state)
      console.log('get State from component after Dispatching :',store.getStat())
    });
  }

Screenshot 3 screenshot image

My question is how can i get the lastess state from the mapped props after dispatching an action

Here is my code

file client.reducer.js,

const initaileState={
    clients:[],
    loading:true,
    error:""
}
const ClientReducer=(state=initaileState,action)=>{
    switch (action.type) {
        case clientConstant.POST_CLIENTS.REQUEST:
            return {
                ...state,
                error:'',
                loading: true
            }
        case clientConstant.POST_CLIENTS.SUCCESS:
            return {
                ...state,
                clients: [...state.clients,action.payload],
                error:'',
                loading: false
            }
        case clientConstant.POST_CLIENTS.FAILURE:
            return {
                ...state,
                error:action.payload,
                loading: false
            }
        default:
            return state
    }
}

file client.action.js,

const postClientRequest = (client)=>dispatch => {
     dispatch({
        type: clientConstant.POST_CLIENTS.REQUEST,
    })
    return axios.post('http://localhost:5000/client', client)
}

const postClientSuccess = (client) =>dispatch =>{
    return dispatch({
        type: clientConstant.POST_CLIENTS.SUCCESS,
        payload: client
    })
}

const postClientFailure = (error) =>dispatch =>{
    return dispatch({
        type: clientConstant.POST_CLIENTS.FAILURE,
        payload: error
    })
}

export const postClient = client => dispatch => {

    return dispatch(postClientRequest(client)).then(res => {
        const client = res.data;
        dispatch(postClientSuccess(client));
    }).catch(err => {
        dispatch(postClientFailure(err.message))
    })
}

file index.js

const store = createStore(combineReducers({clients:ClientReducer}), composeEnhancers(

    applyMiddleware(thunk,Logger)
));
console.log('Get State  before dispatching : ',store.getState());
store.dispatch(postClient(client)).then(()=>{
    console.log('Get State  after dispatching : ',store.getState());
})

ReactDOM.render(
 <Provider store={store}>
    <App store={store} />
  </Provider>,
  document.getElementById('root')
);

//App.js
function App({state,store}) {
  const client ={
    "firstName":"adam",
    "lastName":"ben",
    "email":"[email protected]",
    "phone":"7939909838720"
  };
  const dispatch =useDispatch();

  const ClickBtn=()=>{
    console.log('get State from component before Dispatching :',store.getStat())
    console.log('before Dispatching:',state)
    dispatch(postClient(client)).then(()=>{
      console.log('after Dispatching:',state)
      console.log('get State from component after Dispatching :',store.getStat())
    });
  }
  return (
    <div className="App">
      <header className="App-header">
       <button  onClick={ClickBtn}>Dispatch </button>
      </header>
    </div>
  );
}

const mapStateToProps=state=>{
  return {state}
}

export default connect(mapStateToProps)(App);
1

There are 1 answers

0
ruslanv On

You need to return the values you need from the store state

const mapStateToProps = state => {
  return {
    // you named this property as `clients` in combineReducers
    clients: state.clients
  }
}

then they will be available in component's props. Component will listen to the redux state change and auto-update props.

//App.js
function App({ state, props }) {
console.log(props.clients)

Also, the value you pass to the component as a prop can be accessed via prop object, not directly.

ReactDOM.render(
 <Provider store={store}>
    <App store={store} />
  </Provider>,
  document.getElementById('root')
);


//App.js
function App({ state, props }) {
console.log(props.store)