这是我前端开发自学一年后在Stackoverflow上的第一个问题。我已经为我的疑问找到了答案,但由于这些问题第三次出现,我认为现在是时候向网络提问了。
我正在尝试建立一个图书馆服务,访客用户可以登录、预订书籍、添加到愿望清单、归还等。对于前端,我使用
react
、react-router
、react-bootstrap
和 redux-toolkit
。由于我对后端还不了解,所以我使用 json-server
获取数据,它监视一个简单的数据库,其中有两个大对象:users
和书籍 catalogue
。
代码中有一个
<Catalogue />
组件,它向 json-server' to get the data (with
useEffect), which is stored in the state. When data is fetched, it renders
` 组件发送请求,其中包含必要的信息和两个按钮。其中一个是打算预订一本书。预订按钮背后的逻辑是:
仅当一切正常时,代码才会调度使用
createAsyncThunk
中的 catalogueSlice
创建的操作。在这个 thunk 中,它从数据库中删除了这本书的副本,并将结果传递给 extrareducers
来更新状态。 handleClick 函数是 async
并等待此操作结束。操作完成后,代码将调度另一个操作,即使用 createAsyncThunk
中的 userSlice
创建的操作,该操作会更新数据库,将该书添加到该用户的当前预订中,并且像另一个 thunk 一样,将结果传递给状态,并更新用户的状态。
我的主要问题
dispatch
在 thunk 中调用 thunkAPI
可以吗?我的其他疑问
使用
useAppSelector
检索状态通常更好,还是在可能的情况下通过子级 props
传递状态?
到目前为止,我已经有了
reserve
、addToWishlist
、login
、register
,它们都是用createAsyncThunk
创建的,并且在切片的extrareducers
中产生了大量代码。我计划添加更多内容,这将是向服务器发送请求的其他 thunk。这个工作流程可以吗?我在后端犯了一些严重的逻辑错误?
我不明白,这就是
thunk
和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!')
}
}
主要问题的答案。
据我所知,上述 IF 语句的正确位置是React 组件。 分派操作意味着在App工作流程中涉及Redux Store。所以让商店介入是没有用的,只是为了检查条件。它还有助于保持商店切片中的代码干净。
渴望知道您其他疑问的答案。
我认为,对于可用性和用户角色等条件:
disabled
按钮。"out of stock", "already reserved"
之类的帮助文本,以获得更好的用户体验。