如何使用useState只更新对象数组中的特定对象



我刚刚在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>
)}

并且addLikeremoveLike函数应该更新post,这将强制重新渲染组件。因此,它应该如预期的那样发挥作用。

相关内容

  • 没有找到相关文章

最新更新