hooks使用之forwardRef
forwardRef 是一个高阶组件
高阶组件: 接受一个组件作为参数 , 返回一个新的组件
forwardRef给函数组件扩展了一个属性 叫ref属性
forwardRef 将允许你给函数组件挂ref,同时给函数组件扩展了一个属性叫做ref, 属性作为函数组件的第二个参数存在, 此时的ref你可以用来传递任何你想要传递的数据
forwardRef 一般都是和组件ref连用的 不会单独使用
函数组件就是一个函数 一个函数的执行我们无非可以得到两个东西:
- 函数的引用
- 函数的返回值
// app
function App() {
const testInputRef = useRef(null)
const handlerClick = useCallback(() => {
testInputRef.current.focus()
}, [])
return (
<div className="App">
<StudentList />
<Counter/>
<Ticker />
{/* 给组件挂 ref */}
{/* react 类组件 过去给类组件挂ref 可以得到类组件的实例, 类组件挂载 相当于帮忙做了new的操作 */}
{/* 但是有一种场景是有必要的, 我有可能在这个父组件里面去访问子组件的一些东西 */}
<TestInput ref={ testInputRef } />
<button onClick={handlerClick}>父组件 clickme</button>
</div>
);
}
// TestInput
import { forwardRef, useCallback, useRef } from "react"
function TestInput(props, parentRef) {
// 设计理念 就是react始终希望组件的props是纯净的, 属性一旦变化, 就会造成组件的重新渲染
// 但是我们知道ref的变动是不会造成组件的从新渲染
// 其实我们要避免一个东西的不确定性 我们应该尽量去保证一个东西的稳定性
const inputElRef = useRef(null)
const handlerClick = useCallback(() => {
inputElRef.current.focus()
}, [inputElRef])
return (
<div>
<input ref={parentRef} />
<button onClick={handlerClick}>click me</button>
</div>
)
}
// 给子组件挂载ref 就是要要求子组件区最佳forwardRef的
// 同时forwardRef会得到的这个ref属性通过第二个参数传递给真实的函数组件
export default forwardRef(TestInput)
实现
function myForwardRef(Component) {
return function (props) {
const {ref, ...realProps} = props
return Component(realProps, ref)
}
}