簡體   English   中英

React state object 中的變異值

[英]Mutating value in a React state object

問這樣一個簡單的問題我覺得很愚蠢,但由於某種原因,我忘記了如何更改 React state object 中的值。 例如:

const initialState = {
   likes: 100,
   dislikes: 25,
   isLiked: false,
   isDisliked: false
}

const [data, setData] = useState(initialState)

const handleLikes = e => {
    if (data.isLiked) {
        setData({ ...data, likes: data.likes - 1 });
    } else {
        setData({ ...data, likes: data.likes + 1 });
    }

    setData({ ...data, isLiked: !data.isLiked })
}

<button className={`like-button ${data.isLiked ? 'liked' : ''}`} onClick={handleLikes}>Like | <span className='likes-counter'>{data.likes}</span></button>

令人困惑的部分,讓我問這個問題的部分,是喜歡:data.likes + 1部分。 當我單擊按鈕時,它會按預期添加/刪除 className,但值永遠不會改變。 我知道這是一件很簡單的事情,但我已經花了一段時間。

喜歡有什么問題: data.likes + 1

隨后的兩個setData調用最終會相互“覆蓋”,因為在您調用setData后,您的handleLikes捕獲的data不會發生變化。

您將希望使用setState的函數形式能夠可靠地查看當前值(即使異步修改在隊列中,然后基於它返回一個新值:

const handleToggleLikes = (e) => {
  setData((data) =>
    data.isLiked
      ? { ...data, likes: data.likes - 1 }
      : { ...data, likes: data.likes + 1 },
  );
  setData((data) => ({ ...data, isLiked: !data.isLiked }));
};

您可以在一次調用中完成這兩項修改:

const handleToggleLike = e => {
    setData(data => ({
        ...data,
        likes: data.likes + (data.isLiked ? -1 : 1),  // decrease if previously liked
        isLiked: !data.isLiked,
    }));
}

有兩種方法可以使用 setState function 來更新 state object:

  1. 將新的 state object 傳遞給它(這是您在代碼中所做的)
  2. Pass it a callback function that takes the current state object as argument, uses it to create the new state object, and returns the new state object.

每當你想使用當前的 state object 來創建新的 state ZA8CFDE6331BD59EB2666F891ZB 時,你必須使用第二種方式。 在您的情況下,您的代碼:

setData({...data, likes: data.likes - 1})

使用當前的 state object(數據)創建新的 state ZA8CFDE6331BD59EB2AC966F8911C46。 因此,您必須改用回調,如下所示:

setData((cur_data)=>({...cur_data, likes: cur_data.likes-1}))

請注意,我在回調 function 中使用箭頭語法來返回新的 state object。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM