When dispatching my toggleLiked()
function from ImageCard.tsx
component no slices except for the last one ( toggleLikedAction
) get called. likeImageStart
and likeImageSuccess
both get ignored. Why? This means my isLoading
state is always false and I never get feedback over the pending status of my API call, which means I never render my spinner :(
ImageCard.tsx
export function ImageCard({ image }: ImageProp): ReactElement {
const [liked, setLiked] = useState(image.tags.includes(TAGS.FAV));
const isLoading = useSelector(imagesAreLoading);
const dispatch = useDispatch();
const handleClick = (public_id: string, tag: string) => {
setLiked(!liked);
dispatch(toggleLiked(public_id, tag));
};
return (
<div className="card mb-5 portfolio-item">
<div className="card-image">
<img className="image" src={image.secure_url} alt="" />
</div>
<span onClick={() => handleClick(image.public_id, TAGS.FAV)}>
{!isLoading && <FontAwesomeIcon icon={liked ? heartSolid : heartOutline} size="lg" color="black" />}
{isLoading && <img className="spinner" src={Spinner} alt="Loading Spinner" />}
</span>
</div>
);
}
imageSlice.ts
export function toggleLiked(public_id: string, tag: string) {
return async (dispatch) => {
dispatch(likeImageStart); // HERE
try {
const response = await fetch(LIKE_URL, {
method: 'PUT',
body: JSON.stringify({ public_id, tag }),
headers: { 'Content-Type': 'application/json' },
});
const data = await response.json();
if (response.ok) {
dispatch(likeImageSuccess); // HERE
dispatch(toggleLikedAction({ public_id, tag })); // HERE
} else {
const key = Object.keys(data)[0];
const message = data[key] ? data[key][0] : response.statusText;
throw Error(message);
}
} catch (error) {
dispatch(likeImageFailure(error.message));
}
};
}
imageSlice
const initialState: ImageState = {
images: [],
isLoading: false,
error: '',
};
export const imageSlice = createSlice({
name: 'image',
initialState,
reducers: {
likeImageStart: (state: ImageState) => {
state.isLoading = true;
},
likeImageSuccess: (state: ImageState) => {
state.isLoading = false;
state.error = '';
},
likeImageFailure: (state: ImageState, { payload }) => {
state.isLoading = false;
state.error = payload;
},
toggleLikedAction: (state: ImageState, { payload }) => {
state.isLoading = false;
const { public_id, tag } = payload;
const likedImage = state.images.find((image) => image.public_id === public_id);
const index = likedImage?.tags.indexOf(tag) || 0;
index > -1 ? likedImage?.tags.splice(index, 1) : likedImage?.tags.push(tag);
},
},
});
dispatch(likeImageStart)
should have been dispatch(likeImageStart())
. I forgot the round braces to call the actual reducer. My bad!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.