我应该处理我的动作创建者中的错误吗

IT技术 reactjs react-redux
2022-07-07 00:33:30

在以下情况下,我应该如何处理可能的错误:

export async function testAction(data) {

    try {
        let response = await axios.get(`https://jsonplaceholder.typicode.com/todos/1`);
        return {
            type: 'TEST_ACTION',
            payload: response
        }
    } catch(err) {
        // ???
    }

}

// 组件中的某处:

<Button onClick={ () => dispatch( testAction() ) }>
    Test Stuff
</Button>

或者更好地从组件实际调度,例如:

重构动作创建者:

export async function testAction(data) {

        try {
            let response = await axios.get(`https://jsonplaceholder.typicode.com/todos/1`);
            return response
        } catch(err) {
            return err
        }

}

组件中的某处:

const handleTestAction = () => {
   testAction().then(r => dispatch( { type: 'TEST_ACTION', payload: r } ) ).catch( // hadnle errors)
}

<Button onClick={ handleTestAction }>
   Test Stuff
</Button>

我知道 redux 风格指南建议使用Action Creators来调度动作,但在这种特殊情况下,我首先调用动作然后使用调度。我应该如何处理它?

2个回答

您可以创建另一个 reducer 来处理错误。

   export async function testAction(data) {

        try {
            let response = await axios.get(`https://jsonplaceholder.typicode.com/todos/1`);
            return {
                type: 'TEST_ACTION',
                payload: response
            }
        } catch(err) {
            return {
                type: 'ERROR',
                payload: err
            }
        }

    }

但是你不能像上面那样做因为这个过程是异步的

为此,您必须使用“redux-thunk”。将其作为中间件添加到商店后,您可以将调度程序添加到您的操作创建器中,这样您就可以在完成后在测试操作中发送任何内容。

所以你的减速器应该改为下面的,

   export async function testAction(data) {

     return (dispatch) => {
        try {
            let response = await 
            axios.get(`https://jsonplaceholder.typicode.com/todos/1`);

            dispatch({
               type: 'TEST_ACTION',
                payload: response
           })
        } catch(err) {
            dispatch({
               type: 'ERR',
                payload: response
           })
        }           
     }

    }

更新

连接中间件后,您可以在操作创建器中使用调度,

const store = createStore(
    reducers,
    {},
    applyMiddleware(thunk)
);

您只需要像上面一样将 thunk 添加到商店。

您可以通过重构您的代码使其更清晰,如下所示

export const testAction = () => async (dispatch) => {
     try {
            let response = await axios.get(`https://jsonplaceholder.typicode.com/todos/1`);
            dispatch({
               type: 'TEST_ACTION',
                payload: response
           })
        } catch(err) {
            dispatch({
               type: 'ERR',
                payload: response
           })
     }
}

如果您的 API 将在 dev 和 prod 模式下发生变化,您可以使用以下方式,

在你的应用程序的某个地方,

 const axiosInstatnce = axios.create({
    baseURL: "https://jsonplaceholder.typicode.com",
    headers: {/* you can set any header here */}
  });

现在,当您创建商店时,

const store = createStore(
 reducers,
 {},
 applyMiddleware(thunk.withExtraArgument(axiosInstatnce))
);

现在您可以获取 axiosInstance 作为您从 testAction 返回的函数的第三个参数。第二个参数给出当前状态。

 export const testAction = () => async (dispatch, state, api) => {
     try {
            let response = await api.get(`/todos/1`);
            dispatch({
               type: 'TEST_ACTION',
                payload: response
           })
        } catch(err) {
             dispatch({
               type: 'ERR',
                payload: response
           })
     }
}

现在在你的组件中,

import {testAction} from '../path/to/actions'

    const dispatch = useDispatch()

    dispatch(testAction())

如果要在动作创建器中编写异步代码,则需要编写异步动作创建器。常规动作创建者返回一个对象,而异步动作创建者返回一个函数而不是对象。

export function testAction(data) {
   return async function(dispatch) {
      // async code
   }
}

在异步操作创建者返回的函数中,您可以访问该函数,以dispatch在服务器成功响应的情况下调度任何成功操作,如果发生错误,您可以调度一个指示发生错误的操作。

export function testAction(data) {
    return async function (dispatch) {
        try {
            let response = await axios.get(`https://jsonplaceholder.typicode.com/todos/1`);

            dispatch({
              type: 'TEST_ACTION',
              payload: response
            });

       } catch(err) {
           dispatch({type: 'TEST_ACTION_ERROR', message: 'error occurred'});
       }
   }
}

如果您的代码中有异步操作创建者,您还需要使用redux-thunk中间件。这个中间件允许动作创建者返回一个函数。

有关如何创建异步操作创建者以及如何设置redux-thunk中间件以使异步创建者工作的完整详细信息,请查看异步操作