点击点赞按钮后,整个网站都消失了,但刷新网页后它会增加,为什么会发生这种情况



我正在使用一个带有伪造json服务器的视频应用程序网站。一切都很顺利,但当我想喜欢一个视频时,问题出现了,它消失了,并抛出了一个错误:Objects are not valid as react child。为什么会发生这种情况?

整个状态切片:

import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"
import { getVideo, updateReaction } from "./videoApi"
//initializing the state
const initialState = {
video: {}, //while we are going to push a single video into the state we should put it an object instance...
loading: false,
isError: false, 
error: ''
}
// async thunk for getting single video
export const fetchVideo = createAsyncThunk('vidoes/fetchVideo', async (id) => {
const videos = await getVideo(id);
return videos;
});
// another async thunk to react on a single video (like or dislike)
export const fetchReact = createAsyncThunk('video/reaction', async ({ id, reaction }) => {
const videoReaction = await updateReaction({ id, reaction })
return videoReaction;
})
//creating slice 
const videoSlice = createSlice({
name: 'video',
initialState,
extraReducers: (builder) => {
builder.addCase(fetchVideo.pending, (state) => {
state.loading = true;
state.isError = false;
})
builder.addCase(fetchVideo.fulfilled, (state, action) => {
state.loading = false;
state.video= action.payload;
})
builder.addCase(fetchVideo.rejected, (state, action) => {
state.loading = false;
state.isError = true;
state.error = action.error?.message;
state.video = [];
})
//writing codes for emplementing like funcitonality 
builder.addCase(fetchReact.pending, (state) => {
return state;
})
builder.addCase(fetchReact.fulfilled, (state, action) => {
state.video.likes = action.payload;
state.video.unlikes = action.payload;
})
builder.addCase(fetchReact.rejected, (state) => {
return state;
})
}
});
export default videoSlice.reducer;

这是一个视频api

import axios from '../../utils/axios'
export const getVideo = async (id) => {
const response = await axios.get(`/videos/${id}`)
return response.data;
}
export const updateReaction = async ({ id, reaction }) => {
console.log(id)
const { data } = await axios.get(`/videos/${id}`)
if (data) {
let updatedReaction =
reaction === 'like'
? {
likes: data.likes + 1,
}
: {
unlikes: data.unlikes + 1,
};
const response = await axios.patch(`/videos/${id}`, updatedReaction);
return response.data;
}
}

视频描述组件

import LIke from '../Like/LIke';
const VidoeDescription = ({ video }) => {
const { title, date, description, likes, unlikes, id } = video;
return (
<div>
<h1 className="text-lg font-semibold tracking-tight text-slate-800">
{title}
</h1>
<div className="pb-4 flex items-center space-between border-b">
<h2 className="text-sm leading-[1.7142857] text-slate-600 w-full">
Uploaded on {date}
</h2>
<LIke likes={likes} unlikes={unlikes} id={id} />
</div>
<div className="mt-4 text-sm text-[#334155] dark:text-slate-400">
{description}
</div>
</div>
);
};
export default VidoeDescription;

类似组件我放我的类似和不同组件

import React from 'react';
import { useDispatch } from 'react-redux';
import LikeImg from '../../assets/like.svg';
import UnLikeImg from '../../assets/unlike.svg'
// import { updateReaction } from '../../features/video/videoApi';
import { fetchReact } from '../../features/video/video_slice';
const LIke = ({ likes, unlikes, id }) => {
console.log(id)
const dispatch = useDispatch();
//handle like features
const reactionHandler = ({ id, reaction }) => {
dispatch(fetchReact({ id, reaction }))
}
return (
<div className="flex gap-10 w-48">
<div className="flex gap-1">
<div
className="shrink-0 cursor-pointer"
onClick={() => reactionHandler({ id, reaction: 'like' })}
>
<img className="w-5 block" src={LikeImg} alt="Like" />
</div>
<div className="text-sm leading-[1.7142857] text-slate-600">
{likes >= 1000 ? `${ likes }K` : likes}
</div>
</div>
<div className="flex gap-1">
<div
onClick={() => reactionHandler({ id, reaction: 'unlike' })}
className="shrink-0 cursor-pointer"
>
<img className="w-5 block" src={UnLikeImg} alt="Unlike" />
</div>
<div className="text-sm leading-[1.7142857] text-slate-600">
{unlikes >= 1000 ? `${ unlikes }K` : unlikes}
</div>
</div>
</div>
);
};
export default LIke;

这是根视频页面

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
import Player from '../component/Player/Player';
import VidoeDescription from '../component/VideoDescription/VidoeDescription';
import { fetchVideo } from '../features/video/video_slice';
import Loading from '../component/Loading/Loading';
import RelatedVideo from '../component/VideoList/RelatedVideo';
const Videos = () => {
const { loading, isError, video, error } = useSelector(state => state.video)
const { id, link, title , tags } = video || {};
const dispatch = useDispatch()
const { videoId } = useParams();
useEffect(() => {
dispatch(fetchVideo(videoId))
}, [dispatch, videoId])
//decide what to render in the ui
let content = null;
if (loading) {
content = <Loading />
}
if (loading && isError) {
content = <div className="col-span-12"><srong>{error}</srong></div>
}
if (!loading && !isError && video?.id) {
content = <div className="col-span-12"><srong>{error}</srong></div>
}
if (!loading && !isError && video?.id) {
content = <div className="mx-auto max-w-7xl px-2 pb-20 min-h-[400px]">
<div className="grid grid-cols-3 gap-2 lg:gap-8">
<div className="col-span-full w-full space-y-8 lg:col-span-2">
<Player link={link} title={title} />
<VidoeDescription video={video} />
</div>
<RelatedVideo currentId={id} tags={tags} />
</div>
</div>
}
return (
<div>
<section className="pt-6 pb-20">
{content}
</section>
</div>
);
};
export default Videos;

问题

此处:

builder.addCase(fetchReact.fulfilled, (state, action) => {
state.video.likes = action.payload;
state.video.unlikes = action.payload;
})

action.payload看起来像这样:

{
likes: 1,
}

因为这就是你在updateReaction中创建它的方式

解决方案

你想这样做:

builder.addCase(fetchReact.fulfilled, (state, action) => {
state.video.likes = action.payload.likes;
state.video.unlikes = action.payload.unlikes;
})

相关内容

最新更新