在以下上下文中,我应该如何处理可能的错误:
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 样式指南建议使用操作创建者来调度操作,但在这种特殊情况下,我首先调用操作,然后使用调度。我应该如何处理它?
您可以创建另一个化简器来处理错误。
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 将在开发和生产模式下更改,您可以使用以下方式,
在您的应用程序中的某个地方,
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
请查看异步操作