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对象。