简体   繁体   中英

Why are my actions not being called in Redux-Toolkit slice

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM