react中修改參數值沒有重新渲染問題-關於淺拷貝與深拷貝


項目中遇到個問題,有一個數組參數,刪除數組中一個元素,並且重新改變state但是頁面沒有重新渲染,先面用一個簡單的todolist重現下問題

如下渲染出來menu,當我點擊刪除時觸發onClose事件,在onClose中直接對listData進行操作,打印出的數據是刪除后的,但是頁面沒有重新渲染

const data=[
  {name:'小A',age:'10',id:'1'},
  {name:'小B',age:'11',id:'2'},
  {name:'小C',age:'10',id:'3'},
  {name:'小D',age:'11',id:'4'}
]
function ToDoList(){
  const [listData,setListData] = useState([data]);

  const onClose=(newdata,e)=>{
    e.stopPropagation();
    e.preventDefault();
    const currentIndex = listData.findIndex(item=>item.id===newdata.id);
    listData.splice(currentIndex,1)
    setListData(listData)
  }
  return (
           <Menu selectedKeys={[currentId]}>
      { listData.map((item,index)=>{
          return (
              <Menu.Item key={index}>
                {item.name}
                <Icon type="close" onClick={(e) => onClose(item,e)} />
              </Menu.Item>
              )
        })
      }
    </Menu>
  )
}
export default ToDoList;

問題出在我不應該直接操作listData,因為直接操作listData使它的值直接變化,在通過setListData()修改他的狀態,這時候通過setListData()保存的最新狀態和listData是相同的,會默認為state並沒有發生改變,所有不會重新渲染,所以,我們需要在處理數據之前對listData做一次深拷貝,如下 

const onClose=(newdata,e)=>{
    e.stopPropagation();
    e.preventDefault();
    const currentIndex = listData.findIndex(item=>item.id===newdata.id);
    const newArray = _.map(taskbarData,(val) => { return val }) 
    newArray.splice(currentIndex,1)
    setListData(newArray)
  }

這樣的話就可以完美解決了

總結:這里涉及到了深拷貝和淺拷貝的問題,

淺拷貝,就是兩個變量都是指向一個地址,改變了一個變量,那另一個變量也隨之改變。這就是淺拷貝帶來的副作用,兩個變量會相互影響到,因為它們指向同一個地址。如下當我改變newArray的值,listData也會隨之改變

const newArray = listData

深拷貝,就是互相獨立,指向的是不同的地址,一個變量改變了,另一個變量不會被影響到。

const newArray = _.map(taskbarData,(val) => { return val })
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM