我刚刚使用 js 文件创建了我的示例 Redux 工具包。现在我正在尝试将它们转换为打字稿。现在修复了一些错误。但我不知道如何解决下面的两个错误。
请参考我在下面代码中的评论,请帮助我解决问题
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from "axios";
export interface UserState {
username: string;
email: string;
isFetching: boolean;
isSuccess: boolean;
isError: boolean;
errorMessage: string;
}
interface check {
name: string;
email: string;
password: string;
}
const initialState: UserState = {
username: "",
email: "",
isFetching: false,
isSuccess: false,
isError: false,
errorMessage: "",
}
export const signupUser = createAsyncThunk(
'users/signupUser',
//
//
// async ({ name, email, password} ... <<< This is the problem 1.
//
async ({ name, email, password }, thunkAPI) => {
try {
const response = await fetch(
'https://mock-user-auth-server.herokuapp.com/api/v1/users',
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name,
email,
password,
}),
},
);
const data = await response.json();
console.log('data', data);
if (response.status === 200) {
localStorage.setItem('token', data.token);
return { ...data, username: name, email };
}
return thunkAPI.rejectWithValue(data);
} catch (e) {
console.log('Error', e.response.data);
return thunkAPI.rejectWithValue(e.response.data);
}
},
);
export const loginUser = createAsyncThunk(
'users/login',
async ({ email, password }, thunkAPI) => {
try {
const response = await fetch(
'https://mock-user-auth-server.herokuapp.com/api/v1/auth',
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
password,
}),
},
);
const data = await response.json();
console.log('response', data);
if (response.status === 200) {
localStorage.setItem('token', data.token);
return data;
}
return thunkAPI.rejectWithValue(data);
} catch (e) {
console.log('Error', e.response.data);
thunkAPI.rejectWithValue(e.response.data);
}
},
);
export const fetchUserBytoken = createAsyncThunk(
'users/fetchUserByToken',
async ({ token }, thunkAPI) => {
try {
const response = await fetch(
'https://mock-user-auth-server.herokuapp.com/api/v1/users',
{
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: token,
'Content-Type': 'application/json',
},
},
);
/* test case for Axios
const response = await axios.get(
'https://mock-user-auth-server.herokuapp.com/api/v1/users',
{
headers: {
Accept: 'application/json',
Authorization: token,
'Content-Type': 'application/json',
},
},
);
*/
const data = await response.json();
console.log('data', data, response.status);
if (response.status === 200) {
return { ...data };
}
return thunkAPI.rejectWithValue(data);
} catch (e) {
console.log('Error', e.response.data);
return thunkAPI.rejectWithValue(e.response.data);
}
},
);
export const userSlice = createSlice({
name: 'user',
initialState: {
username: '',
email: '',
isFetching: false,
isSuccess: false,
isError: false,
errorMessage: '',
},
reducers: {
clearState: state => {
state.isError = false;
state.isSuccess = false;
state.isFetching = false;
return state;
},
},
////
//// [signupUser.fulfilled] ... <<<< this is the problem 2.
////
////
extraReducers: {
[signupUser.fulfilled]: (state, { payload }) => {
console.log('payload', payload);
state.isFetching = false;
state.isSuccess = true;
state.email = payload.user.email;
state.username = payload.user.name;
},
[signupUser.pending]: state => {
state.isFetching = true;
},
[signupUser.rejected]: (state, { payload }) => {
state.isFetching = false;
state.isError = true;
state.errorMessage = payload.message;
},
[loginUser.fulfilled]: (state, { payload }) => {
state.email = payload.email;
state.username = payload.name;
state.isFetching = false;
state.isSuccess = true;
return state;
},
[loginUser.rejected]: (state, { payload }) => {
console.log('payload', payload);
state.isFetching = false;
state.isError = true;
state.errorMessage = payload.message;
},
[loginUser.pending]: state => {
state.isFetching = true;
},
[fetchUserBytoken.pending]: state => {
state.isFetching = true;
},
[fetchUserBytoken.fulfilled]: (state, { payload }) => {
state.isFetching = false;
state.isSuccess = true;
state.email = payload.email;
state.username = payload.name;
},
[fetchUserBytoken.rejected]: state => {
console.log('fetchUserBytoken');
state.isFetching = false;
state.isError = true;
},
},
});
export const { clearState } = userSlice.actions;
export const userSelector = (state: { user: UserState}) => state.user;
答案 0 :(得分:1)
您需要为放入的参数定义类型。如果您只想输入第一个参数并且可以使用 thunkAPI
的默认值,则可以使用
export const signupUser = createAsyncThunk(
'users/signupUser',
async ({ name, email, password }: ArgumentType, thunkAPI) => {
否则,您必须按照 https://redux-toolkit.js.org/usage/usage-with-typescript#createasyncthunk
中的说明声明泛型参数const fetchUserById = createAsyncThunk<
// Return type of the payload creator
MyData,
// First argument to the payload creator
number,
{
dispatch: AppDispatch
state: State
extra: {
jwt: string
}
}
>('users/fetchById', async (userId, thunkApi) => {
对于问题 #2,请注意我们不鼓励使用 extraReducers
的对象映射表示法,因为它通常不太安全,并且在 TypeScript 中不起作用。请使用 https://redux-toolkit.js.org/api/createSlice#the-extrareducers-builder-callback-notation