亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

按鈕不會根據api調用在react js中改變狀態

按鈕不會根據api調用在react js中改變狀態

Smart貓小萌 2023-06-09 15:12:56
我有一個顯示單個帖子的頁面,我有一個喜歡按鈕。如果帖子被點贊,當用戶單擊按鈕時,它會將其狀態更改為“不喜歡”按鈕,但如果帖子不被點贊,則會注冊“贊”并將 id 推送到數組中,但按鈕狀態沒有更新,我必須重新加載頁面才能看到該頁面。有人可以告訴我如何解決這個問題嗎?這是代碼:    const [liked, setLiked] = useState(false)    const [data, setData] = useState([]);    function likePosts(post, user) {        post.likes.push({ id: user });        setData(post);        axiosInstance.post('api/posts/' + post.slug + '/like/');        window.location.reload()    }    function unlikePosts(post, user) {        console.log('unliked the post');        data.likes = data.likes.filter(x => x.id !== user);        setData(data);        return (            axiosInstance.delete('api/posts/' + post.slug + '/like/')        )    }對于按鈕:{data.likes && data.likes.find(x => x.id === user) ?        (<FavoriteRoundedIcon style={{ color: "red" }}            onClick={() => {                unlikePosts(data, user)                setLiked(() => liked === false)            }           }        />)        : (<FavoriteBorderRoundedIcon               onClick={() => {               likePosts(data, user)               setLiked(() => liked === true)               }        }        />)    }謝謝,請詢問是否需要更多詳細信息。
查看完整描述

1 回答

?
慕桂英4014372

TA貢獻1871條經驗 獲得超13個贊

您的主要問題是您直接改變狀態而不是調用函數setState。

為了清楚起見,我重命名datapost,因為您已經說過這是一個代表一篇文章數據的對象。

const?[post,?setPost]?=?useState(initialPost);

您不需要使用likedas 狀態,因為我們已經可以post通過查看我們的用戶是否在post.likes數組中來從數據中訪問此信息。這使我們擁有“單一的事實來源”,我們只需要在一個地方進行更新。

const?isLiked?=?post.likes.some((like)?=>?like.id?===?user.id);

我對likes數組感到困惑。它看起來像是一組對象,它們只是{id: number},在這種情況下,您應該只擁有一組喜歡該帖子的用戶的 ID。但也許對象中還有其他屬性(如用戶名或時間戳)。

在為像博客文章這樣的復雜事物設計組件時,您希望分解出可以在應用程序的其他地方使用的小塊。我們可以定義一個LikeButton顯示我們內心的。這是一個不處理任何邏輯的“演示”組件。它只需要知道是否發帖isLiked以及要做什么onClick。

export const LikeButton = ({ isLiked, onClick }) => {

? const Icon = isLiked ? FavoriteRoundedIcon: FavoriteBorderRoundedIcon;

? return (

? ? <Icon

? ? ? style={{ color: isLiked ? "red" : "gray" }}

? ? ? onClick={onClick}

? ? />

? );

};

我們關于喜歡和不喜歡的很多邏輯可能會被分解成某種usePostLike鉤子,但我還沒有完全優化它,因為我不知道你的 API 在做什么以及我們應該如何響應我們得到的響應.

當用戶單擊贊按鈕時,我們希望更改立即反映在 UI 中,因此我們調用setPost并從數組中添加或刪除當前用戶likes。我們必須用一個新對象設置狀態,所以我們復制所有不隨展開運算符改變的帖子屬性...post,然后likes用編輯過的版本覆蓋該屬性。?filter()并且concat()都是返回數組新副本的安全數組函數。

我們還需要調用 API 來發布更改。您在“喜歡”和“不同”場景中使用相同的 url,因此我們可以調用廣義函數并將方法名稱或作為參數傳遞給對象,而不是調用axios.postand?。我們可能可以以類似的方式組合我們的兩個調用,并將and更改為一個函數。但就目前而言,這就是我所擁有的:axios.deleteaxios.request'post''delete'configsetPostlikePost()unlikePost()toggleLikePost()

export const Post = ({ initialPost, user }) => {

? const [post, setPost] = useState(initialPost);


? const isLiked = post.likes.some((like) => like.id === user.id);


? function likePost() {

? ? console.log("liked the post");

? ? // immediately update local state to reflect changes

? ? setPost({

? ? ? ...post,

? ? ? likes: post.likes.concat({ id: user.id })

? ? });

? ? // push changes to API

? ? apiUpdateLike("post");

? }


? function unlikePost() {

? ? console.log("unliked the post");

? ? // immediately update local state to reflect changes

? ? setPost({

? ? ? ...post,

? ? ? likes: post.likes.filter((like) => like.id !== user.id)

? ? });

? ? // push changes to API

? ? apiUpdateLike("delete");

? }


? // generalize like and unlike actions by passing method name 'post' or 'delete'

? async function apiUpdateLike(method) {

? ? try {

? ? ? // send request to API

? ? ? await axiosInstance.request("api/posts/" + post.slug + "/like/", { method });

? ? ? // handle API response somehow, but not with window.location.reload()

? ? } catch (e) {

? ? ? console.log(e);

? ? }

? }


? function onClickLike() {

? ? if (isLiked) {

? ? ? unlikePost();

? ? } else {

? ? ? likePost();

? ? }

? }


? return (

? ? <div>

? ? ? <h2>{post.title}</h2>

? ? ? <div>{post.likes.length} Likes</div>

? ? ? <LikeButton onClick={onClickLike} isLiked={isLiked} />

? ? </div>

? );

};


查看完整回答
反對 回復 2023-06-09
  • 1 回答
  • 0 關注
  • 173 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號