redux async thunk,API不断响应待处理
我正在创建一个有关目标跟踪器的应用程序。当我从一个帐户注销时,一切都可以,除了注销陷入待处理状态。
控制台上也存在错误,说无法读取null(读取'token')dashboard.jsx的属性:20
。
dashboard.jsx
import React from 'react';
import { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import GoalForm from '../components/GoalForm';
import Spinner from '../components/Spinner';
import { getGoals, reset } from '../features/goals/goalSlice';
import GoalItem from '../components/GoalItem';
function Dashboard() {
const navigate = useNavigate();
const dispatch = useDispatch();
const { user } = useSelector(store => store.auth);
const { goals, isLoading, isError, message } = useSelector(
store => store.goals,
);
useEffect(() => {
if (isError) console.log(message);
if (!user) navigate('/login');
dispatch(getGoals());
return () => {
dispatch(reset());
};
}, [user, isError, message, navigate, dispatch]);
if (isLoading) return <Spinner />;
return (
<>
<section className='heading'>
<h1>Welcome {user && user.name}</h1>
<p>Goals Dashboard</p>
</section>
<GoalForm />
<section className='content'>
{goals.length > 0 ? (
<div className='goals'>
{goals.map(goal => (
<GoalItem key={goal._id} goal={goal} />
))}
</div>
) : (
<h3>You have not set any goals</h3>
)}
</section>
</>
);
}
export default Dashboard;
goartlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import goalService from './goalService';
const initialState = {
goals: [],
isError: false,
isSuccess: false,
isLoading: false,
message: '',
};
// Create 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 Goals
export const getGoals = createAsyncThunk('goals/get', 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);
}
});
// Delete goal
export const deleteGoal = createAsyncThunk(
'goals/delete',
async (id, thunkAPI) => {
try {
const token = thunkAPI.getState().auth.user.token;
return await goalService.deleteGoal(id, 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;
})
.addCase(deleteGoal.pending, state => {
state.isLoading = true;
})
.addCase(deleteGoal.fulfilled, (state, action) => {
state.isLoading = false;
state.isSuccess = true;
state.goals = state.goals.filter(
goal => goal._id !== action.payload.id,
);
})
.addCase(deleteGoal.rejected, (state, action) => {
state.isLoading = false;
state.isError = true;
state.message = action.payload;
});
},
});
export const { reset } = goalSlice.actions;
export default goalSlice.reducer;
goalservice.js
import axios from 'axios';
const API_URL = '/api/goals';
// Create goal
const createGoal = async (goalData, token) => {
const config = {
headers: {
'x-auth-token': `${token}`,
},
};
const response = await axios.post(API_URL, goalData, config);
return response.data;
};
// Get goals
const getGoals = async token => {
const config = {
headers: {
'x-auth-token': `${token}`,
},
};
const response = await axios.get(API_URL, config);
return response.data;
};
// Delete goal
const deleteGoal = async (goalId, token) => {
const config = {
headers: {
'x-auth-token': `${token}`,
},
};
const response = await axios.get(`${API_URL}/${goalId}`, config);
// console.log(response);
return response.data;
};
const goalService = {
createGoal,
getGoals,
deleteGoal,
};
export default goalService;
,这是注销部分:builder.addcase.addcase(lokout.fulfill.fulfield,state =&gt {state.user = null});
当我尝试注销时,用户将被记录出来,但错误会连续出现,例如重新渲染页面。该页面本身重新渲染,状态被困在注销中。 删除目标也不起作用
I am creating an app about goal tracker. When I logout from an account, everything goes okay except the the logout gets stuck in pending state.
There is also error in console saying Cannot read properties of null (reading 'token') Dashboard.jsx:20
.
Dashboard.jsx
import React from 'react';
import { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import GoalForm from '../components/GoalForm';
import Spinner from '../components/Spinner';
import { getGoals, reset } from '../features/goals/goalSlice';
import GoalItem from '../components/GoalItem';
function Dashboard() {
const navigate = useNavigate();
const dispatch = useDispatch();
const { user } = useSelector(store => store.auth);
const { goals, isLoading, isError, message } = useSelector(
store => store.goals,
);
useEffect(() => {
if (isError) console.log(message);
if (!user) navigate('/login');
dispatch(getGoals());
return () => {
dispatch(reset());
};
}, [user, isError, message, navigate, dispatch]);
if (isLoading) return <Spinner />;
return (
<>
<section className='heading'>
<h1>Welcome {user && user.name}</h1>
<p>Goals Dashboard</p>
</section>
<GoalForm />
<section className='content'>
{goals.length > 0 ? (
<div className='goals'>
{goals.map(goal => (
<GoalItem key={goal._id} goal={goal} />
))}
</div>
) : (
<h3>You have not set any goals</h3>
)}
</section>
</>
);
}
export default Dashboard;
goalSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import goalService from './goalService';
const initialState = {
goals: [],
isError: false,
isSuccess: false,
isLoading: false,
message: '',
};
// Create 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 Goals
export const getGoals = createAsyncThunk('goals/get', 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);
}
});
// Delete goal
export const deleteGoal = createAsyncThunk(
'goals/delete',
async (id, thunkAPI) => {
try {
const token = thunkAPI.getState().auth.user.token;
return await goalService.deleteGoal(id, 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;
})
.addCase(deleteGoal.pending, state => {
state.isLoading = true;
})
.addCase(deleteGoal.fulfilled, (state, action) => {
state.isLoading = false;
state.isSuccess = true;
state.goals = state.goals.filter(
goal => goal._id !== action.payload.id,
);
})
.addCase(deleteGoal.rejected, (state, action) => {
state.isLoading = false;
state.isError = true;
state.message = action.payload;
});
},
});
export const { reset } = goalSlice.actions;
export default goalSlice.reducer;
goalService.js
import axios from 'axios';
const API_URL = '/api/goals';
// Create goal
const createGoal = async (goalData, token) => {
const config = {
headers: {
'x-auth-token': `${token}`,
},
};
const response = await axios.post(API_URL, goalData, config);
return response.data;
};
// Get goals
const getGoals = async token => {
const config = {
headers: {
'x-auth-token': `${token}`,
},
};
const response = await axios.get(API_URL, config);
return response.data;
};
// Delete goal
const deleteGoal = async (goalId, token) => {
const config = {
headers: {
'x-auth-token': `${token}`,
},
};
const response = await axios.get(`${API_URL}/${goalId}`, config);
// console.log(response);
return response.data;
};
const goalService = {
createGoal,
getGoals,
deleteGoal,
};
export default goalService;
And this is logout part: builder.addCase(logout.fulfilled, state => {state.user = null});
When i try to logout, the user is logged out but the error appears continuously, like re-rendering the page. The page is re-rendered itself and state is stuck in logout.
Delete Goal is also not working
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您必须在尝试获取目标之前检查用户是否已登录
You must check if the user is logged in before attempt to get the goals