我刚刚在React应用程序中实现了类似的系统功能,但现在我一直在努力更改特定对象的状态,而不是整个对象数组。。这就是当前的行为。
{post.likes.some(u => u.user == _id) ? (
<Button
variant="link"
size={`sm`}
className={`mr-1`}
onClick={() => {removeLike(post._id) ; setIconColor('success') ; setLikes(post.likes.length) }}
>
<i className={`fa fa-heart text-${iconColor} like mr-1`}></i>{likes}
</Button>
) : (
<Button
variant="link"
size={`sm`}
className={`mr-1`}
onClick={() => {addLike(post._id) ; setIconColor('danger') ; setLikes(post.likes.length) }}
>
<i className={`fa fa-heart text-${iconColor} like mr-1`}></i>{likes}
</Button>
)}
如前所述,它位于通过对象数组运行的组件内部。
现在,这是我在返回语句之前的组件中的内容:
const [iconColor, setIconColor] = useState('');
const [likes, setLikes] = useState(0);
如果我按原样运行它,它会更新每个对象的状态,而不是我单击的对象。这是我的实际问题:useState((更新多个对象
更新:我也在使用redux thunk:
// @desc Like a post
// @route PUT /api/v1/posts/:id/like
// @access Private
// @status DONE
export const addLike = id => async dispatch => {
try {
const res = await axios.put(`/api/v1/posts/${id}/like`);
return dispatch({
type: UPDATE_LIKES,
payload: {
id,
likes: res.data
}
});
} catch (err) {
return dispatch({
type: POST_ERROR,
payload: { msg: err.response && err.response.statusText, status: err.response && err.response.status }
});
}
};
// @desc Dislike a post
// @route PUT /api/v1/posts/:id/dislike
// @access Private
// @status DONE
export const removeLike = id => async dispatch => {
try {
const res = await axios.put(`/api/v1/posts/${id}/dislike`);
return dispatch({
type: UPDATE_LIKES,
payload: {
id,
likes: res.data
}
});
} catch (err) {
return dispatch({
type: POST_ERROR,
payload: { msg: err.response && err.response.statusText, status: err.response && err.response.status }
});
}
};
然后,这些函数返回一个连接到我的reducer的分派:
case UPDATE_LIKES:
return {
...state,
likes: state.timeline.map((post) =>
post._id === payload.id && { [post._id]: payload.likes.length }
),
// like: !state.like,
// likes: console.log(
// state.timeline.map(post =>
// post._id === payload.id ? { ...post, likes: payload.likes } : post
// )
// ),
loading: false
};
要只更新对象数组中的特定对象,可以尝试以下操作:
let stateObj = {
one: [],
two: [],
three: [],
// and so on
}
所以你可以从这个大状态中获得一个特定的对象或数组,比如:
stateObj.one
现在你可以用它做任何你想做的事情,一旦它的值更新了,就把它替换成原来的值。
您需要一个变量likes
的数组。目前,您只是多次更改同一变量的值。只需将同类数组的索引与父数组的索引相同即可。或者更好的方法是:将赞数存储在邮件/卡片的对象内。
您需要跟踪每个帖子的likes
。为此,您可以使用一些映射,如{ post_id: like_count}
因此,您的状态将变为:
const [likes, setLikes] = useState({});
点击收听者将是:
onClick={() => {addLike(post._id) ; setIconColor('danger') ; setLikes({...likes, [post._id]: post.likes.length}) }}
显示类似计数将是:
<i className={`fa fa-heart text-${iconColor} like mr-1`}></i>{likes[post._id] || 0}
我认为,您不需要状态。据我从你的代码中了解,你可以实现如下所示。
{post.likes.some(u => u.user == _id) ? (
<Button
variant="link"
size={`sm`}
className={`mr-1`}
onClick={() => {removeLike(post._id)}}
>
<i className={`fa fa-heart text-danger like mr-1`}></i>{post.likes.length}
</Button>
) : (
<Button
variant="link"
size={`sm`}
className={`mr-1`}
onClick={() => {addLike(post._id)}}
>
<i className={`fa fa-heart text-success like mr-1`}></i>{post.likes.length}
</Button>
)}
并且addLike
和removeLike
函数应该更新post
,这将强制重新渲染组件。因此,它应该如预期的那样发挥作用。