我正在觀看 Brad Traversy MERN 教程。他在其中創建了一個 Goal Setter 應用程式。我幾乎完成了它,但是在 goalSlice 的 reset() 函式中出現錯誤。不知道實際問題是什么。當從 Dashboard.jsx 調度 reset() 時,在添加目標并在 chrome 的 redux devtool 中查看它們之后。當我按下注銷按鈕時,chrome 掛起并且控制臺顯示此訊息無法讀取 null 的屬性(讀取“令牌”)
我相信這是console.log(message)Dashboard.jsx 中的內容,但我不知道如何解決它。我嘗試評論dispatch(reset())洗掉此錯誤,但我還必須在用戶注銷時重置目標。有人對此有任何想法嗎?
我也在 github 上上傳了我的代碼,所以如果有人需要有關代碼的更多資訊,可以訪問此鏈接:https
://github.com/anishdalvi/MERN-Goal-Setter-.git
Youtube 鏈接:https ://youtu.be /UXjMo25Nnvc
儀表板.jsx
import { useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { useSelector, useDispatch } from 'react-redux'
import GoalForm from '../components/GoalForm'
import Spinner from '../components/Spinner'
import { getGoals, reset } from '../features/goals/goalSlice'
function Dashboard() {
const dispatch = useDispatch()
const navigate = useNavigate()
const { user } = useSelector((state) => state.auth)
const { goals, isLoading, isError, message } = useSelector((state) => state.goals)
useEffect(() => {
if(isError){
console.log("iserror " message)
}
if(!user){
navigate('/login')
}
dispatch(getGoals())
/* return () => {
dispatch(reset())
} */
} , [user, navigate, isError, message, dispatch] )
if (isLoading){
return <Spinner />
}
return (
<>
<section className="heading">
<h1>Welcome {user && user.name}</h1>
<p>Goals Dashboard</p>
</section>
<GoalForm />
</>
)
}
export default Dashboard
目標服務.js
import axios from 'axios'
const API_URL = '/api/goals/'
// create new goal
const createGoal = async (goalData, token) => {
const config = {
headers: {
Authorization: `Bearer ${token}`
}
}
const response = await axios.post(API_URL, goalData, config)
return response.data
}
// get goals
const getGoals = async (token) => {
const config = {
headers: {
Authorization: `Bearer ${token}`
}
}
const response = await axios.get(API_URL, config)
return response.data
}
const goalService = {
createGoal,
getGoals
}
export default goalService
goalSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import goalService from './goalService'
const initialState = {
goals: [],
isError: false,
isSuccess: false,
isLoading: false,
message: ""
}
// create new Goal
export const createGoal = createAsyncThunk('goals/create', async (goalData, thunkAPI) => {
try {
const token = thunkAPI.getState().auth.user.token
return await goalService.createGoal(goalData, token)
} catch (error) {
const message = (error.response && error.response.data && error.response.data.message) || error.message || error.toString()
return thunkAPI.rejectWithValue(message)
}
} )
// get user goals
export const getGoals = createAsyncThunk('goals/getAll', async(_, thunkAPI) => {
try {
const token = thunkAPI.getState().auth.user.token
return await goalService.getGoals(token)
} catch (error) {
const message = (error.response && error.response.data && error.response.data.message) || error.message || error.toString()
return thunkAPI.rejectWithValue(message)
}
})
export const goalSlice = createSlice({
name: 'goal',
initialState,
reducers: {
reset: (state) => initialState,
},
extraReducers:(builder) => {
builder
.addCase(createGoal.pending, (state) => {
state.isLoading = true
})
.addCase(createGoal.fulfilled, (state, action) => {
state.isLoading = false
state.isSuccess = true
state.goals.push(action.payload)
})
.addCase(createGoal.rejected, (state, action) => {
state.isLoading = false
state.isError = true
state.message = action.payload
})
.addCase(getGoals.pending, (state) => {
state.isLoading = true
})
.addCase(getGoals.fulfilled, (state, action) => {
state.isLoading = false
state.isSuccess = true
state.goals = action.payload
})
.addCase(getGoals.rejected, (state, action) => {
state.isLoading = false
state.isError = true
state.message = action.payload
})
}
})
export const { reset } = goalSlice.actions
export default goalSlice.reducer
authService.js
import axios from 'axios'
const API_URL = '/api/users/'
// Register User
const register = async (userData) => {
const response = await axios.post(API_URL, userData)
if(response.data){
localStorage.setItem('user', JSON.stringify(response.data))
}
return response.data
}
// login User
const login = async (userData) => {
const response = await axios.post(API_URL 'login', userData)
if(response.data){
localStorage.setItem('user', JSON.stringify(response.data))
}
return response.data
}
// Logout User
const logout = () => {
localStorage.removeItem('user')
}
const authService = {
register, logout, login
}
export default authService
authSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import authService from './authService'
// Get user from localStorage
const user = JSON.parse(localStorage.getItem('user'))
const initialState = {
user: user ? user : null,
isError: false,
isSuccess: false,
isLoading: false,
message: ""
}
// Register user
export const register = createAsyncThunk('auth/register', async (user, thunkAPI) => {
try {
return await authService.register(user)
} catch (error) {
const message = (error.response && error.response.data && error.response.data.message) || error.message || error.toString()
return thunkAPI.rejectWithValue(message)
}
})
// Login user
export const login = createAsyncThunk('auth/login', async (user, thunkAPI) => {
try {
return await authService.login(user)
} catch (error) {
const message = (error.response && error.response.data && error.response.data.message) || error.message || error.toString()
return thunkAPI.rejectWithValue(message)
}
})
// logout
export const logout = createAsyncThunk('auth/logout' , async () => {
await authService.logout()
})
export const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
reset: (state) => {
state.isLoading = false
state.isSuccess = false
state.isError = false
state.message = ''
}
},
extraReducers: (builder) => {
builder
.addCase(register.pending, (state) => {
state.isLoading = true
} )
.addCase(register.fulfilled, (state, action) => {
state.isLoading = false
state.isSuccess = true
state.user = action.payload
})
.addCase(register.rejected, (state, action) =>{
state.isLoading = false
state.isError = true
state.message = action.payload
state.user = null
})
.addCase(login.pending, (state) => {
state.isLoading = true
} )
.addCase(login.fulfilled, (state, action) => {
state.isLoading = false
state.isSuccess = true
state.user = action.payload
})
.addCase(login.rejected, (state, action) =>{
state.isLoading = false
state.isError = true
state.message = action.payload
state.user = null
})
.addCase(logout.fulfilled, (state) =>{
state.user = null
})
}
})
export const { reset } = authSlice.actions
export default authSlice.reducer
uj5u.com熱心網友回復:
查看此屬性訪問:
thunkAPI.getState().auth.user.token
您正在嘗試訪問授權用戶的令牌。
但是你的初始狀態是這樣的:
const initialState = {
user: user ? user : null,
isError: false,
isSuccess: false,
isLoading: false,
message: ""
}
如果用戶不存在,您如何訪問他們的令牌?
當您呼叫reset()時,您的用戶可能被設定為null,因此錯誤僅出現在該點。
您應該在訪問令牌之前檢查用戶是否為空,并根據需要處理它為空的情況。
if (thunkAPI.getState().auth.user) {
// only in the case the above condition is true,
// then you can access the token.
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/536443.html
標籤:节点.js反应还原
上一篇:發布請求未收到正文
