我的组件设置为显示图书列表,如卡片缩略图。图书列表中的每一项都由此组件生成。每一张卡片都有一个收藏夹图标,点击它将书添加到favoriteTitles
数组中。通过再次按下收藏夹图标,它会从列表中删除它。
const Card = ({ title, history }) => {
const dispatch = useDispatch();
const { favoriteTitles } = useSelector(({ titles }) => titles);
const { id, name, thumbnail } = title;
const [favorite, setFavorite] = useState(favoriteTitles?.some(item => item.titleId === title.id));
const handleFavoriteClick = () => {
const isFavorite = favoriteTitles?.some(item => item.titleId === title.id);
if (isFavorite) {
dispatch(removeFavoriteTitle(title));
setFavorite(false);
} else {
dispatch(addFavoriteTitle(title));
setFavorite(true);
}
};
return (
<CardContainer>
<Thumbnail thumbnail={thumbnail} />
{name}
<FavesIcon isActive={favorite} onClick={handleFavoriteClick} />
</CardContainer>
);
};
这个组件的问题是,当您在FavesIcon
上按一次以添加,如果您改变主意,希望立即删除它并再次按下,则favoritesTitles
数组仍然具有旧的值。
假设我们当前的收藏列表如下所示:
const favoritesTitles = [{titleId: 'book-1'}];
按下收藏夹图标后,Redux中的列表将得到更新:
const favoritesTitles = [{titleId: 'book-1'}, {titleId: 'book-2'}];
如果我再次按下移除它,组件中的favoritesTitles
数组仍然是旧数组,其中包含1项。但是如果我查看Redux,列表会更新并更正。
组件应该如何获得更新的Redux值?
更新
我对每个操作都有特定的端点,其中添加或从收藏夹中删除:
GET: /users/{userId}/favorites
-响应列表(如[{titleId: 'book-1'}, {titleId: 'book-2'}]
)
POST: /users/me/favorites/{titleId}
-空响应
DELETE: /users/me/favorites/{titleId}
-空响应
对于添加或删除项时的每个操作,在成功请求时,我都会分派GET
操作。我的行动是:
export const getFavoriteTitles = userId =>
apiDefaultAction({
url: GET_FAVORITE_TITLES_URL(userId),
onSuccess: data => {
return {
type: 'GET_FAVORITE_TITLES_SUCCESS',
payload: data,
};
},
});
export const addFavoriteTitle = (userId, id) => (dispatch, getState) => {
return dispatch(
apiDefaultAction({
method: 'POST',
url: SET_FAVORITE_TITLES_URL,
data: {
titleId: id,
},
onSuccess: () => {
dispatch(getFavoriteTitles(userId));
return { type: 'SET_FAVORITE_TITLE_SUCCESS' };
},
})
);
};
我的减速机很直截了当,我没有变异任何数组。由于只有GET
请求返回数组列表,所以我不会在还原器中进行任何变异:
case 'GET_FAVORITE_TITLES_SUCCESS':
return {
...state,
favoriteTitles: action.payload,
};
case 'SET_FAVORITE_TITLE_SUCCESS':
return state;
case 'DELETE_FAVORITE_TITLE_SUCCESS':
return state;
发布于 2021-01-07 02:55:45
似乎在添加到收藏夹之后第二次单击FavesIcon
时,GET: /users/{userId}/favorites
请求仍在等待,favoriteTitles
列表尚未更新。这就是为什么组件仍然包含一个旧值的原因。
您需要在触发favoriteTitles
或removeFavoriteTitle
操作后立即更新GET_FAVORITE_TITLES_SUCCESS
列表,而无需等待要分派的GET_FAVORITE_TITLES_SUCCESS
操作。这种模式被称为‘乐观UI':
export const toggleFavorite = itemId => {
return {
type: 'TOGGLE_FAVORITE',
payload: { itemId },
};
}
export const addFavoriteTitle = (userId, id) => (dispatch, getState) => {
dispatch(toggleFavorite(id));
return dispatch(
...
);
};
export const removeFavoriteTitle = (userId, id) => (dispatch, getState) => {
dispatch(toggleFavorite(id));
return dispatch(
...
);
};
你的减速机看起来像这样:
case 'TOGGLE_FAVORITE':
return {
...state,
favoriteTitles: state.favoriteTitles.map(item => item.titleId).includes(action.payload.itemId)
? state.favoriteTitles.filter(item => item.titleId !== action.payload.itemId)
: [...state.favoriteTitles, { titleId: action.payload.itemId }],
};
UPD.,请查看最小工作沙箱实例
https://stackoverflow.com/questions/65596367
复制