我试图用redux工具包做一个注销功能,但是当函数被分派时,它被拒绝了,错误消息是cannot read property of undefined
。
这是我的组件:
import React from 'react'
import { Container, AppBar, Toolbar, styled, InputBase, Button } from '@mui/material'
import { useDispatch, useSelector } from 'react-redux'
import { logoutUser } from '../../reducers/auth/authSlice'
const Search = styled("div")(({theme}) => ({
backgroundColor: "white",
padding: "10px",
borderRadius: "10px",
width: "40%"
}))
export default function Navbar() {
const dispatch = useDispatch();
const isAuthenticated = useSelector(state => state.user.isAuthenticated);
const handleLogout = () => {
dispatch(logoutUser());
console.log(isAuthenticated)
};
return (
<AppBar position='static' color='primary'>
<Container>
<Toolbar>
<Search>
<InputBase placeholder='Search...' fullWidth={true}/>
</Search>
{isAuthenticated ? <Button
type='submit'
variant="contained"
color="primary"
onClick={handleLogout}
>
Logout
</Button> : ''}
</Toolbar>
</Container>
</AppBar>
)
}
我想在我的导航栏中呈现注销按钮,只有当用户被验证时,当我点击注销按钮时,会触发handleLogout,它会调度logoutUser操作。问题是被拒绝了,我不知道为什么。
所以我假设它与我的切片以及我如何开发函数有关
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import setAuthToken from '../../utils/setAuthToken';
import axios from 'axios';
const initialState = {
token: localStorage.getItem('item'),
isAuthenticated: false,
loading: true,
user: null,
error: null
}
export const loadUser = createAsyncThunk(
'user/loadUser',
async ({ rejectWithValue }) => {
if(localStorage.token){
setAuthToken(localStorage.token);
}
try {
const res = axios.get('http://localhost:3000/api/auth');
return res.data;
} catch (error) {
return rejectWithValue(error.response.data);
}
}
)
export const registerUser = createAsyncThunk(
'user/registerUser',
async (newUser, { rejectWithValue }) => {
try {
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const body = JSON.stringify(newUser);
const response = await axios.post(
'http://localhost:3000/api/users',
body,
config
);
return response.data;
} catch (error) {
return rejectWithValue(error.response.data);
}
}
);
export const loginUser = createAsyncThunk('auth/login', async ({ email, password }, { dispatch, rejectWithValue }) => {
const body = { email, password };
const config = {
headers: {
'Content-Type': 'application/json',
},
};
try {
const res = await axios.post('http://localhost:3000/api/auth', body, config);
dispatch(loadUser());
console.log(body)
return res.data;
} catch (err) {
return rejectWithValue(err.response.data);
}
});
export const logoutUser = createAsyncThunk(
'auth/logout',
async (_, { getState, rejectWithValue }) => {
try {
// Remove token from local storage
localStorage.removeItem('token');
// Reset authentication state
const state = getState();
state.user.isAuthenticated = false;
state.user.token = null;
state.user.user = null;
return true;
} catch (err) {
return rejectWithValue(err.response.data);
}
}
);
export const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
},
extraReducers: {
[registerUser.pending]: (state) => {
state.loading = true;
state.error = null;
},
[registerUser.fulfilled]: (state, action) => {
state.user = action.payload;
state.loading = false;
state.error = null;
},
[registerUser.rejected]: (state, action) => {
state.loading = false;
state.error = action.payload;
},
[loadUser.pending]: (state) => {
state.loading = true;
state.error = null;
},
[loadUser.fulfilled]: (state, action) => {
state.isAuthenticated = true;
state.user = action.payload;
state.loading = false;
state.error = false;
},
[loadUser.rejected]: (state, action) => {
state.loading = false;
state.isAuthenticated = false;
state.error = action.payload;
},
[loginUser.pending]: (state) => {
state.loading = true;
state.error = null;
},
[loginUser.fulfilled]: (state, action) => {
state.token = localStorage.setItem('token', action.payload.token);
state.isAuthenticated = true;
state.loading = false;
state.user = action.payload.user;
},
[loginUser.rejected]: (state, action) => {
state.isAuthenticated = false;
state.loading = false;
state.error = action.payload;
},
[logoutUser.pending]: (state) => {
state.loading = true;
state.error = null;
},
[logoutUser.fulfilled]: (state) => {
state.loading = false;
state.isAuthenticated = false;
state.token = null;
state.user = null;
},
[logoutUser.rejected]: (state, action) => {
state.loading = false;
state.error = action.payload;
}
}
})
// Action creators are generated for each case reducer function
export const { } = userSlice.actions
export default userSlice.reducer
1条答案
按热度按时间c3frrgcw1#
在
handleLogout
函数中,唯一可以访问data
属性的地方是logoutUser
函数中的以下行:(next时间,我建议你提供一个最小复制示例和/或错误堆栈跟踪,以便其他人可以更快地找到它)。
这表明您的代码抛出了一些错误,这些错误被
catch
块捕获。但是,err.response
是undefined
,这意味着err
不是Axios错误,尽管您的错误处理程序期望这样做。更好的方式来写这一行:
这可以确保您不会访问不存在的嵌套属性,并且始终有一个参数传递给
rejectWithValue
。然后,您可以检查实际错误并找出代码抛出错误的原因。