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