- useRef在每次執行時返回的是同一個引用(返回的ref對象在組件的整個生命周期內保持不變)
- 在函數組件中可以使用useRef和createRef
- 但useRef性能比createRef好,快
- 在類組件中,createRef是在初始化constructor時被賦值的(執行一次)
類組件中的createRef
23 Refs的應用場景與選用思考
25 Refs轉發機制與在高階組件中的使用
函數組件useRef
import { createRef, forwardRef, useRef } from 'react'
const Foo = forwardRef((params, inputRef) => {// 第一個參數寫params 不要用null占位return (<><input type="text" ref={inputRef} /></>)
})
const App = () => {const inputRef = useRef()// 效果相同,性能有差異// const inputRef = createRef()const focus = () => {inputRef.current.focus()}return (<><button onClick={focus}>聚焦</button><Foo ref={inputRef} /></>)
}
export default App
比較createRef和useRef
window.arr1 = []
window.arr2 = []const App = () => {const [num, setNum] = useState(0)const useRef1 = useRef()const createRef1 = createRef()window.arr1.push(useRef1) // 每項指向相同的引用window.arr2.push(createRef1) // 每項指向不同的引用return (<><span>{num}</span><br /><button onClick={() => setNum(num + 1)}>add</button></>)
}
回調方式設置ref
類組件
const App = () => {let refSpan;return (<><span ref={dom => {refSpan = dom}}>{1}</span><br /><button onClick={() => console.log('dom', refSpan)}>add</button></>)
}
函數組件
class App extends Component {refSpan;render() {return (<><span ref={dom => {this.refSpan = dom}}>{1}</span><br /><button onClick={() => console.log('dom', this.refSpan)}>add</button></>)}
}
useImperativeHandle的使用與實現
perative 英[?m?per?t?v]
美[?m?per?t?v]
adj. 重要緊急的; 迫切的; 急需處理的; 表示權威的; 表示命令的; 祈使的;
n. 重要緊急的事; 必要的事; 祈使語氣; 祈使語氣動詞;
import { createRef, forwardRef, useRef } from 'react'
// 實現useImperativeHandle
const useImperativeHandle = (ref, cb) => {ref.current = cb()
}
const Foo = forwardRef((params, ref) => {// 第一個參數寫params 不要用null占位const inputRef = useRef()const focus = () => {inputRef.current.focus()}useImperativeHandle(ref, () => {return {focus}})return (<><input type="text" ref={inputRef} /></>)
})
const App = () => {const inputRef = useRef()// 效果相同,性能有差異// const inputRef = createRef()const focus = () => {// 收攏父組件的權限,只暴露focus方法console.log('inputRef', inputRef)inputRef.current.focus()}return (<><button onClick={focus}>聚焦</button><Foo ref={inputRef} /></>)
}
export default App