Reputation: 31
I am updating a user in my react & redux application. And on successfull update i.e fetch (PUT) request, I want to show an alert message "User is successfully updated". But I am not getting any way to do the same. Below is my component, action & reducer code.
userComponent.js
import React from 'react';
import {updateUserData} from '../redux/actions/user';
const mapStateToProps = (state) =>{
return{
updating_user_pending: state.usersData.updating_user_pending,
}
}
const mapDispatchToProps = (dispatch) =>{
return{
updateUserAction: (data) =>{dispatch(updateUserData(data))}
}
}
Class Users extends React.Component{
constructor(){
super();
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit(values) {
this.props.updateUserAction(values);
}
render(){
return(
<form className="form" onSubmit={handleSubmit(this.onSubmit)}>
<div className="form-group">
<label className="label">First Name</label>
<Field className="form-control" name="first_name" component="input" type="text" />
</div>
<div className="form-group">
<label className="label">Email</label>
<Field className="form-control" name="email" component="input" type="email" />
</div>
<button className="btn btn-primary">{(updating_user_pending)?'Submitting...':'Submit'}</button>
</form>
);
}
export default connect(mapStateToProps,mapDispatchToProps)(Users);
action.js
export function updateUserData(data){
return function(dispatch){
dispatch({type: UPDATE_USER_PENDING});
fetch('https://reqres.in/api/users/'+data.user_id, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(res=>{
if(res.status===200){
dispatch({type: UPDATE_USER_SUCCESS});
}else{
dispatch({type: UPDATE_USER_FAILED});
}
})
.catch(err=>{
dispatch({type: UPDATE_USER_FAILED});
})
}
}
reducer.js
import {
UPDATE_USER_PENDING,
UPDATE_USER_SUCCESS,
UPDATE_USER_FAILED
} from '../actions/action-types';
const initialState = {
updating_user_pending:false
}
const userReducer = function(state = initialState, action) {
switch(action.type) {
case UPDATE_USER_PENDING:
return {
...state,
updating_user_pending: true
}
case UPDATE_USER_SUCCESS:
return {
...state,
updating_user_pending: false
}
case UPDATE_USER_FAILED:
return {
...state,
updating_user_pending: false
}
default:
return state;
}
}
export default userReducer;
So basicall, I want to show the success & error notification on the basis of api responses. Any help on this will be really appreciated.
Upvotes: 3
Views: 8568
Reputation: 16122
Show the toast in your action function
import { toast } from 'react-toastify';
export function updateUserData(data) {
return function(dispatch) {
dispatch({ type: UPDATE_USER_PENDING });
fetch('https://reqres.in/api/users/' + data.user_id, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(res => {
if (res.status === 200) {
dispatch({ type: UPDATE_USER_SUCCESS });
// here
toast.success("User updated");
} else {
dispatch({ type: UPDATE_USER_FAILED });
}
})
.catch(err => {
dispatch({ type: UPDATE_USER_FAILED });
});
};
}
In your UserComponent import
import { ToastContainer} from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css'
// ... your code
render(){
return(
<form className="form" onSubmit={handleSubmit(this.onSubmit)}>
<div className="form-group">
<label className="label">First Name</label>
<Field className="form-control" name="first_name" component="input" type="text" />
</div>
<div className="form-group">
<label className="label">Email</label>
<Field className="form-control" name="email" component="input" type="email" />
</div>
<button className="btn btn-primary">{(updating_user_pending)?'Submitting...':'Submit'}</button>
<ToastContainer />
</form>
);
Upvotes: 2
Reputation: 181
UserComponent.js
import React from 'react';
import {updateUserData} from '../redux/actions/user';
const mapStateToProps = (state) =>{
return{
updating_user_pending: state.usersData.updating_user_pending,
}
}
const showResult = () => {
window.alert('success');
}
const mapDispatchToProps = (dispatch) =>{
return{
updateUserAction: (data) =>{dispatch(updateUserData(data, showResult))}
}
}
Class Users extends React.Component{
constructor(){
super();
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit(values) {
this.props.updateUserAction(values);
}
render(){
return(
<form className="form" onSubmit={handleSubmit(this.onSubmit)}>
<div className="form-group">
<label className="label">First Name</label>
<Field className="form-control" name="first_name" component="input" type="text" />
</div>
<div className="form-group">
<label className="label">Email</label>
<Field className="form-control" name="email" component="input" type="email" />
</div>
<button className="btn btn-primary">{(updating_user_pending)?'Submitting...':'Submit'}</button>
</form>
);
}
export default connect(mapStateToProps,mapDispatchToProps)(Users);
action.js
export function updateUserData(data, showResult){
return function(dispatch){
dispatch({type: UPDATE_USER_PENDING});
fetch('https://reqres.in/api/users/'+data.user_id, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(res=>{
if(res.status===200){
dispatch({type: UPDATE_USER_SUCCESS});
showResult();
}else{
dispatch({type: UPDATE_USER_FAILED});
}
})
.catch(err=>{
dispatch({type: UPDATE_USER_FAILED});
})
}
}
Upvotes: 0
Reputation: 96
It looks like what you're trying to do here is a "side effect" (or sometimes just "effect").
A side effect is basically a shorter way of saying: "When X occurs, also do Y". In your case "When "update success" also "show notice" — "show notice" is a side effect of "update success".
Because you probably don't want to put your logic for "show success notice" inside the user form component (because it's not part of the user form), and you also don't want to put it in your reducer (because it's not reducer logic). You want to put it "somewhere else" — you want to put it in a "side effect".
There are a few libraries to help with this "effect business", and since you are using redux; why not have a look at redux-saga? Do note though: It's quite a big dependency, some would call it a language in itself. But it's super powerful, especially if you build your application with it in mind.
You could also create your own redux middleware, where you listen for the UPDATE_USER_SUCCESS
action, and then act accordingly — Maybe call on anther action named ADD_SUCCESS_NOTICE
with a message or similar, then have some other component render that notice somewhere — that's usually how I do it.
If you use function components, then you can also use useEffect
(and other hooks) if you use react hooks.
You could also implement some generic notice system, like for instance "toasts". Here's a tutorial for that.
Upvotes: 1