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
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
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
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);
You need to return the values you need from the store state
then they will be available in component's props. Component will listen to the redux state change and auto-update props.
Also, the value you pass to the component as a prop can be accessed via prop object, not directly.