- 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