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