簡體   English   中英

更改 state 后 useEffect 未觸發

[英]useEffect not getting trigger after state change

我正在制作一個自定義下拉列表,允許在下拉列表中推送新項目。 由於某種原因,useEffect 沒有在 state 更改時觸發,而是在初始渲染時觸發。 我很確定我錯過了一些小東西,但看不到它。 當用戶單擊綁定到“addNewOptionToTree”方法的按鈕時,應該推送新項目。 然后 categoryList 應該在下拉列表中顯示新項目。 控制台日志被觸發並且新的 arr 出現了......有什么想法嗎?

以上回報:

    const [newOption, setNewOption] = useState('')

    const [categoryList, setCategoryList] = useState(["Calendars", "Meetings", "Apostrophes work!"])

    useEffect(() => {
        console.log("categoryList::::::::::::::::", categoryList)
      }, [categoryList]);
    
    
      function addNewOptionToTree() {
        console.log('category:', categoryList);
        console.log('newOption:', newOption);
        const categoryListArr = categoryList
        categoryListArr.push(newOption)
        setCategoryList(categoryListArr)
        console.log("category:", categoryListArr);
    
      }

在返回塊中:

<div className='dropDownList'>
          <div className='listItem' key={'add-item-key'}>
            <Input
              type='text'
              label=''
              value={newOption}
              placeholder='Add New Category'
              onChange={val => setNewOption(val)}
            />
          <div className='icon-add-contain dropdown-add-btn' onClick={addNewOptionToTree}></div>
          </div>
          {
            categoryList.length > 0 &&
              categoryList.map((category, index) => (
                <div className='listItem' onClick={onOptionClicked(category)} key={'level1-'+index}>
                  {category}
                </div>
              ))
          }
        </div>

在您的情況下,它不會被更改,因為您是objects ,並且arrays在 JS 中是通過引用而不是值進行比較的。

例如

let foo = {bar: 1}
let faz = foo
let notFoo = {bar: 1}
foo === faz // true
foo === notFoo // false

話雖如此,在這里:

 const categoryListArr = categoryList // you are passing categoryList by reference
 categoryListArr.push(newOption)
 setCategoryList(categoryListArr)

你正在直接改變你的 state,這通常不好。 為此,您需要以不可變的方式創建categoryListArr數組

 const categoryListArr = [...categoryList] // this is a new array, which contains the same items from the state
 categoryListArr.push(newOption)
 setCategoryList(categoryListArr)

現在你的useEffect將被觸發。

問題是您正在使用數組來比較和觸發useEffect,因此它會在初始渲染時觸發數組長度的變化,但如果長度相同並且只有任何元素發生變化,則會觸發后續更改,這不會觸發useEffect

您可以使用 JSON.stringify

useEffect(() => {
        console.log("categoryList::::::::::::::::", categoryList)
      }, [JSON.stringify(categoryList)]);

只是改變

const categoryListArr = categoryList
categoryListArr.push(newOption)
setCategoryList(categoryListArr)

setCategoryList([...categoryList, newOption]);

這將更改 Array 引用並觸發效果。

暫無
暫無

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

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