我刚刚在我的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>
)}
如前所述,它位于通过对象数组运行的组件内部。
现在,这就是我在return语句之前的组件中的内容:
const [iconColor, setIconColor] = useState('');
const [likes, setLikes] = useState(0);
如果我按原样运行它,它将更新每个单个对象的状态,而不是我单击的对象的状态。这是我的实际问题: useState() updating muliple objects
更新:我也在使用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
};
答案 0 :(得分:0)
您需要具有一个变量likes
的数组。目前,您只是多次更改同一变量的值。只需将like数组的索引与父数组的索引相同即可。甚至更好:将赞数存储在帖子/卡片的对象中。
答案 1 :(得分:0)
要仅更新对象数组中的特定对象,可以尝试以下操作:
let stateObj = {
one: [],
two: [],
three: [],
// and so on
}
因此您可以从这种大状态获取特定的对象或数组,例如:
stateObj.one
现在您可以执行此操作,一旦其值更新,只需将其替换为原来的。
答案 2 :(得分:0)
您需要为每个帖子跟踪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}
答案 3 :(得分: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
,这将强制重新渲染组件。因此,它应该可以按预期工作。