如何在 React 中处理多个错误响应?

How to handle multiple error response in React?

好的,所以我使用 Redux 和 Axios 将 post 数据发送到我的服务器,然后在我的组件中呈现服务器响应、错误或其他情况。有多个 post 请求的响应填满了 Redux 存储,我试图在触发时呈现这些响应。

我在我的组件中收到来自服务器的响应,如下所示:

const createdPost = useSelector( state => state.createPost );
const { loading: createdPostLoading, error: createdPostError, success: createdPostSuccess } = createdPost;

const uploadedImage = useSelector( state => state.uploadImage );
const { loading: uploadedImageLoading, error: uploadedImageError, success: uploadedImageSuccess } = uploadedImage;

const deletedImage = useSelector( state => state.deleteImage);
const { loading: deletedImageLoading, error: deletedImageError, success: deletedImageSuccess } = deletedImage;

所以在我的 useEffect 中,我正在检查它们的值并渲染它们,就像这样:

const [ responseMessage, setResponseMessage ] = useState( '' );

useEffect( () => {

         if ( createdPostError ) {
            setResponseMessage( createdPostError );
        } else if ( createdPostSuccess ) {
            setResponseMessage( createdPostSuccess );
        } else if ( uploadedImageError ) {
            setResponseMessage( uploadedImageError );
        } else if ( uploadedImageSuccess ) {
            setResponseMessage( uploadedImageSuccess );
        } else if ( deletedImageError ) {
            setResponseMessage( deletedImageError );
        } else if ( deletedImageSuccess ) {
            setResponseMessage( deletedImageSuccess );
        }

}, [ createdPostError, createdPostSuccess, uploadedImageError, uploadedImageSuccess, deletedImageError, deletedImageSuccess ] );

渲染函数如下所示:

{
     <Message type='Error' text={responseMessage} />
}

现在的问题是,每当我尝试删除图像但服务器无法删除它时,我都会收到 uploadedImageSuccess 响应,我想我是从已经填充了它的商店那里得到的先前从服务器上传的图像响应。我应该得到删除图像响应。如果我记录 deletedImageError 的值,那么我可以看到实际的服务器响应。它不呈现它。

正在触发 uploadedImageSuccesss 的 useEffect 中的条件语句。所以我猜这不是处理错误的正确方法。有人知道处理它们的好方法吗?我哪里错了?

更新

完整代码如下:

Redux:

=================
CONSTANTS.js:
=================

export const CREATE_POST_REQUEST = 'CREATE_POST_REQUEST';
export const CREATE_POST_SUCCESS = 'CREATE_POST_SUCCESS';
export const CREATE_POST_FAIL    = 'CREATE_POST_FAIL';

export const UPLOAD_IMAGE_REQUEST = 'UPLOAD_IMAGE_REQUEST';
export const UPLOAD_IMAGE_SUCCESS = 'UPLOAD_IMAGE_SUCCESS';
export const UPLOAD_IMAGE_FAIL    = 'UPLOAD_IMAGE_FAIL';

export const DELETE_IMAGE_REQUEST = 'DELETE_IMAGE_REQUEST';
export const DELETE_IMAGE_SUCCESS = 'DELETE_IMAGE_SUCCESS';
export const DELETE_IMAGE_FAIL    = 'DELETE_IMAGE_FAIL'; 

=================
REDUCERjs
=================

export const createPostReducer = ( state = { campaign: {} }, action ) => {

    switch ( action.type ) {
        case CREATE_POST_REQUEST:
            return { loading: true };
        case CREATE_POST_SUCCESS:
            return {
                loading: false,
                success: action.payload
            };
        case CREATE_POST_FAIL:
            return {
                loading: false,
                error: action.payload
            };
        default:
            return state;
    }

}

export const uploadImageReducer = ( state = {}, action ) => {

    switch ( action.type ) {
        case UPLOAD_IMAGE_REQUEST:
            return { loading: true };
        case UPLOAD_IMAGE_SUCCESS:
            return {
                loading: false,
                success: action.payload
            };
        case UPLOAD_IMAGE_FAIL:
            return {
                loading: false,
                error: action.payload
            };
        default:
            return state;
    }

}

export const deleteImageReducer = ( state = {}, action ) => {

    switch ( action.type ) {
        case DELETE_IMAGE_REQUEST:
            return { loading: true };
        case DELETE_IMAGE_SUCCESS:
            return {
                loading: false,
                success: action.payload
            };
        case DELETE_IMAGE_FAIL:
            return {
                loading: false,
                error: action.payload
            };
        default:
            return state;
    }

}

=================
ACTIONS.js
=================

export const createPost = ( postData ) => async ( dispatch ) => {
    
    try {

        dispatch({
            type: CREATE_POST_REQUEST
        });


        const { data } = await axios.post( '/api/posts', postData);

        dispatch({
            type: CREATE_POST_SUCCESS,
            payload: data.message
        });

    } catch ( error ) {

        dispatch({ 
            type: CREATE_POST_FAIL,
            payload: error.message
        });
        
    }

}

export const uploadImage = ( imageData ) => async ( dispatch ) => {
    
    try {

        dispatch({
            type: UPLOAD_IMAGE_REQUEST
        });

        const { data } = await axios.post( '/api/posts/upload-image', imageData );

        dispatch({
            type: UPLOAD_IMAGE_SUCCESS,
            payload: data
        });

    } catch ( error ) {

        dispatch({ 
            type: UPLOAD_IMAGE_FAIL,
            payload: error.message
        });
        
    }

}

export const deleteImage = ( imageData ) => async ( dispatch ) => {
    
    try {

        dispatch({
            type: DELETE_IMAGE_REQUEST
        });

        const { data } = await axios.post( '/api/posts/delete-image', imageData );

        dispatch({
            type: DELETE_IMAGE_SUCCESS,
            payload: data
        });

    } catch ( error ) {

        dispatch({ 
            type: DELETE_IMAGE_FAIL,
            payload: error.message
        });
        
    }

}

=================
STORE.js
=================

const reducer = combineReducers({
    createPost: createPostReducer,
    uploadImage: uploadImageReducer,
    deleteImage: deleteImageReducer
});

const middleware = [ thunk ];

const store = createStore( 
    reducer, 
    initialState, 
    composeWithDevTools( applyMiddleware( ...middleware ) ) 
);

export default store;

组件如下所示:

const Post = () => {

        const [ responseMessage, setResponseMessage ] = useState( '' );

        const createdPost = useSelector( state => state.createPost );
        const { loading: createdPostLoading, error: createdPostError, success: createdPostSuccess } = createdPost;

         const uploadedImage = useSelector( state => state.uploadImage );
         const { loading: uploadedImageLoading, error: uploadedImageError, success: uploadedImageSuccess } = uploadedImage;

         const deletedImage = useSelector( state => state.deleteImage);
         const { loading: deletedImageLoading, error: deletedImageError, success: deletedImageSuccess } = deletedImage;

        useEffect( () => {

              if ( createdPostError ) {
                    setResponseMessage( createdPostError );
               } else if ( createdPostSuccess ) {
                    setResponseMessage( createdPostSuccess );
               } else if ( uploadedImageError ) {
                    setResponseMessage( uploadedImageError );
               } else if ( uploadedImageSuccess ) {
                    setResponseMessage( uploadedImageSuccess );
               } else if ( deletedImageError ) {
                    setResponseMessage( deletedImageError );
               } else if ( deletedImageSuccess ) {
                    setResponseMessage( deletedImageSuccess );
               }

         }, [ createdPostError, createdPostSuccess, uploadedImageError, uploadedImageSuccess, deletedImageError, deletedImageSuccess ] );


    return (

         {
             <Message type='Error' text={responseMessage} />
         }
    )
}

export default Post;

为通用错误处理程序创建单独的 Reducer

export const genericErrorReducer=(state,action){
 switch(action.type){
    case 'GENERIC_ERROR':
    return {
      error:action.payload
    }
 }
}

当您从服务器收到错误时调用它,而不是为每个错误创建单独的本地状态