这是我前端开发自学一年后在Stackoverflow上的第一个问题。我已经为我的疑问找到了答案,但由于这些问题第三次出现,我认为现在是向网络提问的时候了。
我正在尝试构建什么
我正在尝试建立一个图书馆服务,访客用户可以登录、预订书籍、添加到愿望清单、归还等。对于我正在使用的前端react
, react-router
, react-bootstrap
and redux-toolkit
。由于我对后端还不了解,因此我使用以下方式获取数据json-server
,它监视一个简单的数据库,其中有两个大对象:users
和书catalogue
.
我认为应用程序流程
代码中有一个<Catalogue />
组件,它将请求发送到json-server' to get the data (with
使用效果), which is stored in the state. When data is fetched, it renders
` 组件,带有必要的信息和两个按钮。其中一个是打算预订一本书。保留按钮背后的逻辑是:
- verify IF当前用户不是管理员
- verify IF当前用户已经预订了这本书
- verify IF数据库中至少有一本要保留的书
仅当一切正常时,代码才会调度使用创建的操作createAsyncThunk
in catalogueSlice
。在这个 thunk 中,它从数据库中删除了这本书的副本,并将结果传递给extrareducers
更新状态。该handleClick函数是async
并等待此操作结束。操作完成后,代码将分派另一个操作,即使用以下命令创建的操作createAsyncThunk
in userSlice
,它更新数据库,将该书添加到该用户的当前预订中,并且像其他 thunk 一样,将结果传递给状态,并更新用户的状态。
我的疑惑和疑问
我的主要问题
- 上述用于验证用户、当前预订以及数据库中图书是否存在的 IF 语句的正确位置在哪里?在 React 组件中还是在 createAsyncThunk 中?我的意思是:验证是否必须分派某个操作更好,还是分派该操作并在之后阻止它更好?例如可以打电话吗
dispatch
在 thunk 内部使用thunkAPI
?
我的其他疑惑
-
使用以下方式检索状态通常是否更好useAppSelector
或者,如果可能的话,将其传递给孩子们props
?
-
到现在为止,我已经reserve
, addToWishlist
, login
, register
,它们都是用创建的createAsyncThunk
,并导致大量代码extrareducers
的切片。我计划添加更多内容,这将是向服务器发送请求的其他 thunk。这个工作流程可以吗?我在后端犯了一些严重的逻辑错误?
-
没看懂,这和a有什么区别thunk
and a middleware
。有什么有用的资源吗?
这是发送请求的两个主要 thunk。抱歉,他们不是那么干净,但我认为这足以理解这个问题。
export const patchCatalogue = createAsyncThunk(
'catalogue/patch',
async ({book, userInfo}: {
book: IBook;
userInfo: IUserInfo;
}, thunkAPI) => {
const {
id: bookId,
book_status: {
copies,
history,
current
}
} = book;
const {
id: userId,
username
} = userInfo;
try {
const response = await axios.patch(
`http://localhost:5000/catalogue/${bookId}`,
{
book_status: {
copies: copies - 1,
current: [...current, [userId, username]],
}
});
if (response.status === 200) {
const result = await thunkAPI.dispatch(reserve({ book, userInfo }))
// console.log(result)
return response.data;
}
}
catch (error) {
console.error(`PATCH failed - ${error}`)
}
},
);
export const reserve = createAsyncThunk(
'user/reserve',
async ({ book, userInfo }: {
book: IBook;
userInfo: IUserInfo;
}, thunkAPI) => {
const {
id: userId,
reservations: {
current,
history,
}
} = userInfo;
try {
const response = await axios.patch(`http://localhost:5000/users/${userId}`,
{
reservations: {
current: [...current, book],
history: [...history],
}
});
return response.data;
}
catch (error) {
console.error(error)
}
}
);
这是 Button 组件,它调度两个操作。
if (userInfo.role === 'user') {
if (action === 'Book now!') {
const alreadyBooked = userInfo.reservations.current.find(item => item.id === book.id)
if (!alreadyBooked) {
await dispatch(patchCatalogue({ book, userInfo }));
dispatch(reserve({ book, userInfo }))
}
else {
alert('The book is already reserved!')
}
}