我正在学习Udemy课程,他们有一个"不喜欢"和"喜欢"按钮,它们彼此分开。我想尝试将它们变成 1 个按钮,这样按钮就会在不刷新页面的情况下切换和更新喜欢的数量。
我在功能组件中的 return(( 中有这样的东西
{posts.filter(item => item.user.toString() === user).length > 0 ? (
<button onClick={e => unlike(_id)}>Unlike</button>
) : (
<button onClick={e => like(_id)}>Like</button>
)}
此 ony 在页面加载后呈现,它只会呈现"不同于"或"喜欢",具体取决于条件语句。用户只能点赞一次,因此如果用户已经喜欢了一个帖子,在页面加载时,它将加载"不喜欢"按钮,如果用户单击"不喜欢",它将保持"不喜欢",并且不会刷新视图。
我也想更新一下:
{posts.length}
我将如何在不刷新页面的情况下执行此操作,并且它会在用户的操作中重新呈现?
操作/发布.js
// Like
export const like = id => async dispatch => {
try {
const res = await axios.put(`/api/posts/like/${id}`);
dispatch({
type: UPDATE_LIKES,
payload: { id, likes: res.data }
});
} catch (err) {
}
};
// Unlike
export const unlike = id => async dispatch => {
try {
const res = await axios.put(`/api/posts/unlike/${id}`);
dispatch({
type: UPDATE_LIKES,
payload: { id, likes: res.data }
});
} catch (err) {
}
};
减速器/柱.js
import {
GET_POSTS,
POST_ERROR,
UPDATE_LIKES,
ADD_POST
} from '../actions/types';
const initialState = {
posts: [],
post: null,
loading: true,
error: {}
};
export default function(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case GET_POSTS:
return {
...state,
posts: payload,
loading: false
};
case ADD_POST:
return {
...state,
posts: [...state.posts, payload],
loading: false
};
case POST_ERROR:
return {
...state,
posts: payload,
loading: false
};
case UPDATE_LIKES:
return {
...state,
posts: state.posts.map(post =>
post._id === payload.id
? { ...post, likes: payload.likes }
: post
),
loading: false
};
default:
return state;
}
}
在 UNLIKE 方法中,操作类型为">UPDATE_LIKE",而化简器期望">UPDATE_LIKES">
此外,您正在更新化简器中的likes属性,但对于渲染,您正在检查用户属性的条件渲染
/*
you are updating the likes property in your reducer so react will only change the UI if you check the posts.likes instead of posts.user
*/
{posts.filter(item => item.user.toString() === user).length > 0 ? (
<button onClick={e => unlike(_id)}>Unlike</button>
) : (
<button onClick={e => like(_id)}>Like</button>
)}
正在做同样的课程,想做你想做的同样的事情,并看到了这个问题,这就是我所做的,它对我有用。我尝试制作像Instagram这样的"赞"按钮,如果喜欢,心脏会充满红色。
结果的屏幕截图
我发送了一个布尔道具"喜欢",这有助于知道该帖子是否被登录的用户喜欢:
帖子.js
<div className="posts">
{posts.map((post) => (
<PostItem
key={post._id}
post={post}
liked={
post.likes.filter((like) => like.user === user._id).length > 0
? true
: false
}
/>
))}
</div>
邮寄项目.js
此处使用钩子作为按钮的状态。
const [like, setLike] = useState(liked);
<button
type="button"
onClick={async (e) => {
like ? await removeLike(_id) : await addLike(_id);
setLike(!like);
}}
className="btn btn-light"
>
{like ? (
<i className="fas fa-heart like-color"></i>
) : (
<i className="far fa-heart"></i>
)}{" "}
<span>{likes.length}</span>
</button>