如何在打字稿中正确使用 createAsyncThunk 函数?
How do I properly use createAsyncThunk function with typescript?
您可以找到完整的项目 here。
我有以下代码:
extraReducers: (builder) => {
builder
.addCase(getTodosAsync.fulfilled, (state, action:any) => {
return action.payload.todos
})
.addCase(addTodoAsync.fulfilled, (state, action:any) => {
state.push(action.payload.todo)
})
.addCase(toggleCompleteAsync.fulfilled, (state, action:any) => {
const index = state.findIndex(
(todo) => todo.id === action.payload.todo.id
)
state[index].completed = action.payload.todo.completed
})
.addCase(deleteTodoAsync.fulfilled, (state, action:any) => {
return state.filter((todo) => todo.id !== action.payload.id)
})
}
但我想正确键入回调的操作参数,换句话说,摆脱 'any' 类型。我已经发现正确的方法是输入 createAsyncThunk,但直到现在,我都不知道该怎么做。
文件的其余代码如下:
import {
createAsyncThunk,
createSlice,
PayloadAction
} from '@reduxjs/toolkit';
// import {AsyncThunkFulfilledActionCreator} from '../../node_modules/@reduxjs/toolkit/src/createAsyncThunk'
import { nanoid } from 'nanoid';
interface propsPayload {
title?: string,
id?: string,
completed?: boolean
}
const initialState = [
{}
] as Array<propsPayload>
export const getTodosAsync = createAsyncThunk(
'todos/getTodosAsync',
async () => {
const resp = await fetch('http://localhost:7000/todos');
if (resp.ok) {
const todos = (await resp.json()) ;
return { todos } ;
}
}
);
export const addTodoAsync = createAsyncThunk(
'todos/addTodoAsync',
async (payload: propsPayload) => {
const resp = await fetch('http://localhost:7000/todos', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ title: payload.title }),
});
if (resp.ok) {
const todo = await resp.json();
return { todo } ;
}
}
);
export const toggleCompleteAsync = createAsyncThunk(
'todos/completeTodoAsync',
async (payload: propsPayload) => {
const resp = await fetch(`http://localhost:7000/todos/${payload.id}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ completed: payload.completed }),
});
if (resp.ok) {
const todo = await resp.json();
return { todo } ;
}
}
);
export const deleteTodoAsync = createAsyncThunk(
'todos/deleteTodoAsync',
async (payload: propsPayload) => {
const resp = await fetch(`http://localhost:7000/todos/${payload.id}`, {
method: 'DELETE',
});
if (resp.ok) {
return { id: payload.id };
}
}
);
export const todoSlice = createSlice({
name: 'todos',
initialState: initialState,
reducers: {
addTodo: (state: Array<propsPayload>, action: PayloadAction<propsPayload>) => {
const todo = {
id: nanoid(),
title: action.payload.title,
completed: false,
};
state.push(todo);
},
toggleComplete: (state: Array<propsPayload>, action: PayloadAction<propsPayload>) => {
const index = state.findIndex((todo) => todo.id === action.payload.id);
state[index].completed = action.payload.completed;
},
deleteTodo: (state: Array<propsPayload>, action: PayloadAction<propsPayload>) => {
return state.filter((todo) => todo.id !== action.payload.id);
},
},
extraReducers: (builder) => {
builder
.addCase(getTodosAsync.fulfilled, (state, action:any) => {
return action.payload.todos
})
.addCase(addTodoAsync.fulfilled, (state, action:any) => {
state.push(action.payload.todo)
})
.addCase(toggleCompleteAsync.fulfilled, (state, action:any) => {
const index = state.findIndex(
(todo) => todo.id === action.payload.todo.id
)
state[index].completed = action.payload.todo.completed
})
.addCase(deleteTodoAsync.fulfilled, (state, action:any) => {
return state.filter((todo) => todo.id !== action.payload.id)
})
}
});
export const { addTodo, toggleComplete, deleteTodo } = todoSlice.actions;
export default todoSlice.reducer;
但是如果我从操作中删除 'any',就会发生这种情况:
Object is possibly 'undefined'.ts(2532)
(parameter) action: PayloadAction<{
todos: any;
} | undefined, string, {
arg: void;
requestId: string;
requestStatus: "fulfilled";
}, never>
Object is possibly 'undefined'.ts(2532)
(property) payload: {
todos: any;
} | undefined
根本不要输入操作类型。如果您什么都不做,它会根据您的 asyncThunk 的类型正确推断出来。
.addCase(addTodoAsync.fulfilled, (state, action) => {
就像 state
自动是正确的类型一样,action
也是 - addTodoAsync
调度的已完成操作的类型。
您可以找到完整的项目 here。
我有以下代码:
extraReducers: (builder) => {
builder
.addCase(getTodosAsync.fulfilled, (state, action:any) => {
return action.payload.todos
})
.addCase(addTodoAsync.fulfilled, (state, action:any) => {
state.push(action.payload.todo)
})
.addCase(toggleCompleteAsync.fulfilled, (state, action:any) => {
const index = state.findIndex(
(todo) => todo.id === action.payload.todo.id
)
state[index].completed = action.payload.todo.completed
})
.addCase(deleteTodoAsync.fulfilled, (state, action:any) => {
return state.filter((todo) => todo.id !== action.payload.id)
})
}
但我想正确键入回调的操作参数,换句话说,摆脱 'any' 类型。我已经发现正确的方法是输入 createAsyncThunk,但直到现在,我都不知道该怎么做。
文件的其余代码如下:
import {
createAsyncThunk,
createSlice,
PayloadAction
} from '@reduxjs/toolkit';
// import {AsyncThunkFulfilledActionCreator} from '../../node_modules/@reduxjs/toolkit/src/createAsyncThunk'
import { nanoid } from 'nanoid';
interface propsPayload {
title?: string,
id?: string,
completed?: boolean
}
const initialState = [
{}
] as Array<propsPayload>
export const getTodosAsync = createAsyncThunk(
'todos/getTodosAsync',
async () => {
const resp = await fetch('http://localhost:7000/todos');
if (resp.ok) {
const todos = (await resp.json()) ;
return { todos } ;
}
}
);
export const addTodoAsync = createAsyncThunk(
'todos/addTodoAsync',
async (payload: propsPayload) => {
const resp = await fetch('http://localhost:7000/todos', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ title: payload.title }),
});
if (resp.ok) {
const todo = await resp.json();
return { todo } ;
}
}
);
export const toggleCompleteAsync = createAsyncThunk(
'todos/completeTodoAsync',
async (payload: propsPayload) => {
const resp = await fetch(`http://localhost:7000/todos/${payload.id}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ completed: payload.completed }),
});
if (resp.ok) {
const todo = await resp.json();
return { todo } ;
}
}
);
export const deleteTodoAsync = createAsyncThunk(
'todos/deleteTodoAsync',
async (payload: propsPayload) => {
const resp = await fetch(`http://localhost:7000/todos/${payload.id}`, {
method: 'DELETE',
});
if (resp.ok) {
return { id: payload.id };
}
}
);
export const todoSlice = createSlice({
name: 'todos',
initialState: initialState,
reducers: {
addTodo: (state: Array<propsPayload>, action: PayloadAction<propsPayload>) => {
const todo = {
id: nanoid(),
title: action.payload.title,
completed: false,
};
state.push(todo);
},
toggleComplete: (state: Array<propsPayload>, action: PayloadAction<propsPayload>) => {
const index = state.findIndex((todo) => todo.id === action.payload.id);
state[index].completed = action.payload.completed;
},
deleteTodo: (state: Array<propsPayload>, action: PayloadAction<propsPayload>) => {
return state.filter((todo) => todo.id !== action.payload.id);
},
},
extraReducers: (builder) => {
builder
.addCase(getTodosAsync.fulfilled, (state, action:any) => {
return action.payload.todos
})
.addCase(addTodoAsync.fulfilled, (state, action:any) => {
state.push(action.payload.todo)
})
.addCase(toggleCompleteAsync.fulfilled, (state, action:any) => {
const index = state.findIndex(
(todo) => todo.id === action.payload.todo.id
)
state[index].completed = action.payload.todo.completed
})
.addCase(deleteTodoAsync.fulfilled, (state, action:any) => {
return state.filter((todo) => todo.id !== action.payload.id)
})
}
});
export const { addTodo, toggleComplete, deleteTodo } = todoSlice.actions;
export default todoSlice.reducer;
但是如果我从操作中删除 'any',就会发生这种情况:
Object is possibly 'undefined'.ts(2532)
(parameter) action: PayloadAction<{
todos: any;
} | undefined, string, {
arg: void;
requestId: string;
requestStatus: "fulfilled";
}, never>
Object is possibly 'undefined'.ts(2532)
(property) payload: {
todos: any;
} | undefined
根本不要输入操作类型。如果您什么都不做,它会根据您的 asyncThunk 的类型正确推断出来。
.addCase(addTodoAsync.fulfilled, (state, action) => {
就像 state
自动是正确的类型一样,action
也是 - addTodoAsync
调度的已完成操作的类型。