- 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