admin管理员组

文章数量:1410682

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 ponent, 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" ponent="input" type="text" />
            </div>

            <div className="form-group">
              <label className="label">Email</label>
              <Field className="form-control" name="email" ponent="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('/'+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.

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 ponent, 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" ponent="input" type="text" />
            </div>

            <div className="form-group">
              <label className="label">Email</label>
              <Field className="form-control" name="email" ponent="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.

Share edited Mar 30, 2020 at 23:17 Rajat asked Mar 30, 2020 at 22:37 RajatRajat 311 silver badge6 bronze badges 17
  • Depends on what type of alerts you wznt to show. To you have a notifications state in your app? – Incepter Commented Mar 30, 2020 at 22:46
  • I just waana show a simple "window.alert" – Rajat Commented Mar 30, 2020 at 22:46
  • I will use "react-toastify" for future. But for now, Just a simple alert – Rajat Commented Mar 30, 2020 at 22:47
  • To show the window.alert just place it when you dispatch the update user success – Incepter Commented Mar 30, 2020 at 22:48
  • To properly using the notifications and react-toastify, i advice that you create a separate redux state in your app dedicated only for notifications. And dispatch an' action that registers your notification – Incepter Commented Mar 30, 2020 at 22:50
 |  Show 12 more ments

3 Answers 3

Reset to default 2

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" ponent="input" type="text" />
        </div>

        <div className="form-group">
          <label className="label">Email</label>
          <Field className="form-control" name="email" ponent="input" type="email" />
        </div>

        <button className="btn btn-primary">{(updating_user_pending)?'Submitting...':'Submit'}</button>
     <ToastContainer />
     </form>
  );

Example from official docs

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 ponent (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 ponent render that notice somewhere — that's usually how I do it.

If you use function ponents, 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.

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" ponent="input" type="text" />
            </div>

            <div className="form-group">
              <label className="label">Email</label>
              <Field className="form-control" name="email" ponent="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});            
        })
    }
}

本文标签: javascriptShow alert on successfull fetch request in react reduxStack Overflow