Javascript 为什么这个createAsyncThunk行为异常?
我对redux工具包API中的Javascript 为什么这个createAsyncThunk行为异常?,javascript,reactjs,redux,redux-toolkit,Javascript,Reactjs,Redux,Redux Toolkit,我对redux工具包API中的createAsyncThunk有一些问题 export const getPayments = createAsyncThunk('getPayments/all', async ({ rejectWithValue }) => { try { const response = await fetch(`/payments`, { method: 'GET', headers: { 'C
createAsyncThunk
有一些问题
export const getPayments = createAsyncThunk('getPayments/all', async ({ rejectWithValue }) => {
try {
const response = await fetch(`/payments`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
})
console.log('res:', response)
return response
} catch (e) {
console.log('ERROR:', e)
rejectWithValue(e)
}
})
每当我添加rejectWithValue
作为参数时,它总是在redux开发工具中显示为rejected。当我移除它时,它总是满足的。这是怎么回事?我只想调用下面的这个函数,如果提取时出错?为什么它总是拒绝它
编辑:我发现此
无法对“undefined”的属性“rejectWithValue”进行解构,因为它是未定义的。
在现在的响应中,这说明了为什么它总是被拒绝,为什么会发生这种情况,以及我如何修复它?下面是一个示例,如前所述,的rejectWithValue
是第二个参数的属性,有效负载创建者需要返回rejectWithValue
调用的结果,以下是一个示例:
// toggle reject
const reject = ((shouldReject) => () =>
(shouldReject = !shouldReject))(true);
// test thunk action creator
const testAsyncThunk = createAsyncThunk(
'some/test',
// arg is the argument passed to the action creator, can be ignored if not used
async (arg, { rejectWithValue }) => {
console.log('argument passed to action creator:', arg);
if (reject()) {
//return result of rejectWithValue call
return rejectWithValue('rejected');
}
return Promise.resolve('resolved');
}
);
当您分派使用createAsyncThunk
创建的thunk时,除非您使用unwrapResult
,否则结果承诺
下面是一个演示该行为的小应用程序:
import React from 'react';
import ReactDOM from 'react-dom';
import {
createAsyncThunk,
unwrapResult,
} from '@reduxjs/toolkit';
import { Provider, useDispatch } from 'react-redux';
import {
createStore,
applyMiddleware,
compose,
} from 'redux';
// toggle reject
const reject = ((shouldReject) => () =>
(shouldReject = !shouldReject))(true);
// test thunk action creator
const testAsyncThunk = createAsyncThunk(
'some/test',
// arg is the argument passed to the action creator, can be ignored if not used
async (arg, { rejectWithValue }) => {
console.log('argument passed to action creator:', arg);
if (reject()) {
//return result of rejectWithValue call
return rejectWithValue('rejected value');
}
return Promise.resolve('resolved value');
}
);
const reducer = (state, { type, payload }) => {
return state;
};
//creating store with redux devtools and thunk middleware
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
{},
composeEnhancers(
applyMiddleware(
({ dispatch, getState }) => (next) => (action) =>
//minimal implementation of thunk middleware
typeof action === 'function'
? action(dispatch, getState)
: next(action)
)
)
);
const App = () => {
const dispatch = useDispatch();
return (
<button
onClick={() =>
dispatch(testAsyncThunk('argument passed'))
.then(
(resolved) => {
console.log('action resolved with', resolved);
return resolved;
},
(rejected) =>
// this never executes because promise returned
// by dispatch(tunkaction) will not reject
console.log('action rejected with:', rejected)
)
.then(
//after unwrap result you have a promise that will
// reject
unwrapResult
)
.catch((err) =>
console.log('rejected with...', err)
)
}
>
dispatch action
</button>
);
};
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
从“React”导入React;
从“react dom”导入react dom;
进口{
创建异步thunk,
展开结果,
}来自“@reduxjs/toolkit”;
从“react redux”导入{Provider,useDispatch};
进口{
createStore,
applyMiddleware,
组成
}来自“redux”;
//切换拒绝
常量拒绝=((shouldReject)=>()=>
(shouldReject=!shouldReject))(true);
//测试thunk动作创建者
const testAsyncThunk=createAsyncThunk(
“一些/测试”,
//arg是传递给动作创建者的参数,如果不使用,可以忽略
异步(arg,{rejectWithValue})=>{
log('传递给操作创建者的参数:',arg);
if(拒绝()){
//返回rejectWithValue调用的结果
返回rejectWithValue(“拒绝值”);
}
返回承诺。解析(“解析值”);
}
);
const reducer=(状态,{type,payload})=>{
返回状态;
};
//使用redux开发工具和thunk中间件创建存储
康斯特康塞恩汉斯酒店=
窗口。uuu REDUX_vtools_uextension_uuucompose_uu124; COMPOSE;
const store=createStore(
减速器,
{},
复合致癌物(
applyMiddleware(
({dispatch,getState})=>(下一步)=>(操作)=>
//thunk中间件的最小实现
动作类型===‘功能’
?行动(调度、获取状态)
:下一步(行动)
)
)
);
常量应用=()=>{
const dispatch=usedpatch();
返回(
分派(testAsyncThunk('参数已传递'))
.那么(
(已解决)=>{
console.log('action resolved with',resolved);
返回已解决;
},
(被拒绝)=>
//这永远不会执行,因为承诺已经兑现
//通过派遣(tunkaction)不会拒绝
console.log('操作已被拒绝,已被拒绝:')
)
.那么(
//在打开结果后,你有一个承诺
//拒绝
展开结果
)
.catch((错误)=>
console.log('被…拒绝',错误)
)
}
>
派遣行动
);
};
ReactDOM.render(
,
document.getElementById('root'))
);
我认为您应该为异步函数添加第一个属性,例如:async(data,{rejectWithValue})..@AlekseyDubinskiy但我不需要此实例中的任何数据?即使我输入了数据,它仍然会触发“Completed”,即使它跳入catch块??您还需要返回拒绝return rejectWithValue(e)
即使不需要数据,thunkApi
也将作为第二个参数传入该函数。就像JavaScript中的所有地方一样:如果您关心第二个参数而不是第一个参数,那么您仍然需要给第一个参数起一个名字,否则您将永远无法得到第二个参数。不一定是数据
<代码>\u可能是一个很好的选择,表明您不关心它。好的,谢谢。我修好了,但我有个问题。我在createAsyncThunk
中有一个fetch,我在里面放了一个try-catch,它从未“拒绝”过它。甚至当它进入捕捉区时。但是当我删除try/catch并从fetch返回结果时。成功了吗?(也就是说,根据服务器的响应,它要么转到.completed
要么.rejected
。为什么try/catch不起作用?@RedBaron你确定你在catch块中返回return rejectWithValue(someError);
吗?不,我想这可能起作用。稍后再试,让你知道