中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

react中使用usestate踩坑如何解決

發布時間:2022-08-05 10:51:07 來源:億速云 閱讀:513 作者:iii 欄目:開發技術

本篇內容介紹了“react中使用usestate踩坑如何解決”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    usestate的常規用法

    在react框架中,不適用類組件,使用函數式組件又想自定義數據維護業務開發的時候,就需要使用react提供的hook來完成。usestate就是最常見的一種hook。

    const [name,setName] = useState('dx');
    setName('dx1')

    中括號實際是一個解構運算,第一個name是設置的值,第二個setName是只能用來改變name的方法。

    useState遇到的坑

    1、useState不適合復雜對象的更改

    因為useState不能像setState那樣進行合并更新,當使用useState第二個參數進行數據更新的時候,必須傳入一個完整的結構,而不僅僅只是改變的那一部分。

    如果你想讓一個復雜的對象都能實現響應,可以分兩種情況。

    第一種情況,這個復雜的對象每次都是整體發生改變,那么也可以直接使用useState。

    第二種情況,你只是想讓許多的簡單數據都放到一個對象里面,這樣便于統一管理,那我建議,如果這些簡單數據之間都沒什么必然聯系的話,還是分開創建多個state更好。

    在編碼的過程中,我們寧愿以空間復雜度換取時間復雜度,多創建幾個變量和創建一個變量,在用戶體驗上并不會有太多的差別。

    但如果數據過于復雜,diff算法找到對應的變化及發生響應,大規模的重新渲染,這一過程,將會導致用戶體驗下降。

    2、useState異步回調的問題

    當使用usestate對數據進行更新,并不能立刻獲取到最新的數據。

      const [name, setName] = useState('dx');
    
      const handleTest = () => {
        console.log(name) // dx
        setName('dx1')
        console.log(name) // dx
      }

    解決的辦法。

    一、配合useEffect使用

      const [name, setName] = useState('dx');
      const handleTest = () => {
        console.log(name) //dx
        setName('dx1')
        console.log(name)//dx
      }
      
      useEffect(() => {
        console.log(name) //dx1
      },[name])

    二、創建一個新的變量保存最新的數據

      const [name, setName] = useState('dx');
      const handleTest = () => {
        console.log(name) //dx
        const newName = "dx1"
        setName(newName)
        console.log(newName) //dx1
      }

    三、用一個函數包裹,不推薦使用,因為函數里面所有的東西都會全部重新定義

    const [name, setName] = useState('dx');
     function text () {
       const handleTest = () => {
         console.log(name) //dx
         const newName = "dx1"
         setName(newName)
         console.log(name) //dx
         console.log(newName) //dx1
       }
       useEffect(() => {
         console.log(name) //dx1
       },[name])
    
       return (
         <div>
           {name} //點擊之前dx,點擊按鈕之后dx1
          <button type="button" onClick={handleTest }>改變名字</button>
         </div>
       )
     }
    console.log(name) //點擊按鈕之前dx,點擊按鈕之后dx1

    3、根據hook的規則,使用useState的位置有限制

    強調,所有的hook和自定義hook都遵循此規則。

    僅頂層調用 Hook :不能在循環,條件,嵌套函數等中調用useState()。

    在多個useState()調用中,渲染之間的調用順序必須相同。

    僅從React 函數調用 Hook:必須僅在函數組件或自定義鉤子內部調用useState()。

    4、使用useState,回調函數形式更改數據

    const [a, setA] = useState({c:1})
    /** oldA為之前的a,return為設置的新值 */
    setA((oldA) => {
    return {c: oldA.c + 1}
    })

    5、useState存入的值只是該值的引用(引用類型)

    const textObj = {name:'dx'}
    
    const [useState1, setUseState1] = useState(textObj )
    
    const [useState2, setUseState2] = useState(textObj )
    /** usestate的操作不要放在函數的最外層,這里只是簡單的代碼展示,你可以將set操作放在某個函數里面 */
    setUseState1((oldUseState1) => {
    	oldUseState1.age = 18
    return {...oldUseState1}
    })
    
    useEffect(() => {
    	/** 改變一個會導致兩個都改變,深淺拷貝的問題 */
    	console.log(useState1)  // {name: "dx", age: 18}
    	console.log(useState2)  // {name: "dx", age: 18}
    },[
    useState1
    ])

    解決的方案

    const textObj = {name:'dx'}
    
    const [useState1, setUseState1] = useState(textObj )
    
    const [useState2, setUseState2] = useState(JSON.parse(JSON.stringify(textObj)))
    /** usestate的操作不要放在函數的最外層,這里只是簡單的代碼展示,你可以將set操作放在某個函數里面 */
    setUseState1((oldUseState1) => {
    	oldUseState1.age = 18
    return {...oldUseState1}
    })
    
    useEffect(() => {
    	/** 改變一個會導致兩個都改變,深淺拷貝的問題 */
    	console.log(useState1)  // {name: "dx", age: 18}
    	console.log(useState2)  // {name: "dx"}
    },[
    useState1
    ])

    6、useState,如果保存引用數據,useEffect檢測不到變化?

    const textObj = {name:'dx'}
    const [useState1, setUseState1] = useState(textObj)
    /** usestate的操作不要放在函數的最外層,這里只是簡單的代碼展示,你可以將set操作放在某個函數里面 */
    setUseState1((oldUseState1) => {
    	oldUseState1.age = 18
    return oldUseState1
    
    useEffect(() => {
    	console.log(useState1)  
    },[
    useState1
    ])
    //結果是沒有任何反應

    解決方法

    const textObj = {name:'dx'}
    const [useState1, setUseState1] = useState(textObj)
    /** usestate的操作不要放在函數的最外層,這里只是簡單的代碼展示,你可以將set操作放在某個函數里面 */
    setUseState1((oldUseState1) => {
    	oldUseState1.age = 18
    	/** 返回一個新的對象,useEffectc才能檢測得到 */
    return {...oldUseState1}
    
    useEffect(() => {
    	console.log(useState1)  // {name: "dx", age: 18}
    },[
    useState1
    ])

    7、useState無法保存一個函數

    你是否嘗試著將函數的引用作為一個變量保存到useState中去呢?

    比如:

      const testFunciton1 = () => {
        console.log({name: 'dx',age: '18'})
      }
    
      /** usestate保存函數測試 */
      const [stateFunction, setstateFunction] = useState<() => void>(testFunciton1);
    
      useEffect(() => {
       console.log(stateFunction)
      }, [stateFunction])

    打印結果

    react中使用usestate踩坑如何解決

    代碼中從未調用過testFunciton1 ,結果testFunciton1卻被執行了

    useEffect打印出來的卻是一個undefined。

    稍微改動一下代碼,再測試

      const testFunciton1 = () => {
        console.log({name: 'dx',age: '18'})
        return {
          name: 'yx',
          age: '17'
        }
      }
    
      /** usestate保存函數測試 */
      const [stateFunction, setstateFunction] = useState<() => void>(testFunciton1);
    
      useEffect(() => {
       console.log(stateFunction)
      }, [stateFunction])

    結果

    react中使用usestate踩坑如何解決

    很明顯,在useState中,函數會自動調用,并且保存函數返回的值,而不能保存函數本身。

    解決的方案

    使用useState不能保存函數,那么可以使用useCallback這個hook。

      /** useCallback,使用參數與useEffect一致 */
      const testFunction = useCallback(() => {
        // useCallback返回的函數在useCallbak中構建
        const testFunciton1 = () => {
          console.log({ name: 'dx', age: '18' });
          return {
            name: 'yx',
            age: '17',
          };
        };
        return testFunciton1;
      }, []);
    
      useEffect(() => {
        console.log(testFunction());
      }, [testFunction]);

    結果

    react中使用usestate踩坑如何解決

    useState實現原理

    前一段時間面試某大廠的時候,講到了useState這個hook,要求簡單寫一下useState的實現原理,以下代碼只是一個粗淺的原理。

    function useState(init) {
    	let state;
    	// useState無法保存函數
    	if(typeof init === 'function') {
    		state = init()
    	} else {
    		state = init
    	}
    
    	const setState = (change) => {
    		// 判斷一下是否傳遞過來的是函數
    		if(typeof change === 'function') {
    			// 如果是函數,調用,并將之前的state傳過去,接收到的返回值作為新的state并賦值
    			state = change(state)
    		} else {
    			// 如果不是函數,直接賦值
    			state = change;
    		}
    	}	
    	return [state, setState]
    }

    “react中使用usestate踩坑如何解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    藁城市| 赤城县| 瓦房店市| 桐梓县| 浦县| 青阳县| 金阳县| 开鲁县| 车致| 禹城市| 七台河市| 屏边| 龙江县| 合山市| 苍南县| 苏尼特右旗| 璧山县| 綦江县| 虹口区| 怀集县| 鹰潭市| 电白县| 婺源县| 宜城市| 堆龙德庆县| 张家界市| 威信县| 顺昌县| 本溪| 永城市| 九江县| 乌拉特后旗| 赣州市| 临漳县| 晋中市| 景泰县| 邻水| 雷山县| 呼和浩特市| 陈巴尔虎旗| 清涧县|