react閉包導致訪問到舊的state值的處理方法


react函數組件閉包導致事件中獲取到舊的state值的處理辦法。

因為正式場景中的代碼比較復雜,故而徒手擼了一個簡版的例子,代碼中的“useMemo”用來實現某種場景,這里顯得用的相當“做作”,見諒

話不多說,上代碼:

 1 import React, { useState, useMemo } from "react"
 2 
 3 function App() {
 4   const [params, setParams] = useState({
 5     size: 10,
 6     page: 1,
 7   })
 8   const list = useMemo(() => {
 9     return [
10       {
11         key: "aaa",
12         name: "aily",
13         render: (item) => (
14           <button onClick={() => handleClick(item)}>{item.name}</button>
15         ),
16       },
17     ]
18   }, [])
19 
20   const handleClick = (text) => {
21     console.log("params:", params)  //此處只能訪問到初始的params值
22     console.log("text:", text)
23   }
24 
25   return (
26     <div className="App">
27       <button
28         onClick={() => {
29           setParams({ size: 11, page: 2 })
30           console.log("params changes")
31         }}
32       >
33         change params
34       </button>
35       <p>
36         params size: {params.size}, page: {params.page}
37       </p>
38       <ul>
39         {list.map((item) => (
40           <li key={item}>{item.render(item)}</li>
41         ))}
42       </ul>
43     </div>
44   )
45 }
46 
47 export default App

 

效果圖:

 

 

處理辦法:useRef,見代碼

 1 import React, { useState, useMemo, useRef, useEffect } from "react"
 2 
 3 function App() {
 4   const [params, setParams] = useState({
 5     size: 10,
 6     page: 1,
 7   })
 8 
 9   //划重點 這里這里
10 const paramsRef = useRef(params) 11 useEffect(() => { 12 paramsRef.current = params 13 }, [params]) 14 
15   const list = useMemo(() => {
16     return [
17       {
18         key: "aaa",
19         name: "aily",
20         render: (item) => (
21           <button onClick={() => handleClick(item)}>{item.name}</button>
22         ),
23       },
24     ]
25   }, [])
26 
27   const handleClick = (text) => {
28     console.log("params:", params)
29     console.log("paramsRef:", paramsRef)
30     console.log("text:", text)
31   }
32 
33   return (
34     <div className="App">
35       <button
36         onClick={() => {
37           setParams({ size: 11, page: 2 })
38           console.log("params changes")
39         }}
40       >
41         change params
42       </button>
43       <p>
44         params size: {params.size}, page: {params.page}
45       </p>
46       <ul>
47         {list.map((item) => (
48           <li key={item}>{item.render(item)}</li>
49         ))}
50       </ul>
51     </div>
52   )
53 }
54 
55 export default App

 

 

效果圖:

 

 

 

原理:

useRef 返回一個可變的 ref 對象,其 .current 屬性被初始化為傳入的參數(initialValue)。返回的 ref 對象在組件的整個生命周期內保持不變。useRef在每次渲染之后,返回的都是同一個ref對象。

 


免責聲明!

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



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