“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情”
1. 简介
我个人是很喜欢React Hooks的,但是初学者看来是非常混乱的,我们这里就介绍使用一下常用的Hooks
- Hook 只能在函数组件中使用,不能在类组件中使用
1.代码学习
1. useRef
- useRef返回一个可变的ref对象,有一个current属性,初始值为传入的参数(initialValue)。
- 返回的 ref 对象在组件的整个生命周期内持续存在
- 这是一种访问DOM的主要方式,和vue2的ref 是一样的
2. 简单使用
-
引入Hook
import { useRef } from "react"; -
创建一个需要被ref 指定的标签
function App() { return <> <input type="text" /> </> } -
创建hook实例并绑定标签
function App() { const inputRef = useRef<HTMLInputElement>(null); return <> <input ref={inputRef} type="text" defaultValue="20"/> </> } -
通过hook获取到ref对象,再通过该对象的current属性得到dom元素
function App() { const inputRef = useRef<HTMLInputElement>(null); console.log(inputRef.current) console.log(inputRef.current?.value) console.log(inputRef.current?.style) return <> <input ref={inputRef} type="text" defaultValue="20"/> </> } -
上面直接console 可能获取不到 建议使用 useEffect
useEffect(() => { console.log(inputRef.current) console.log(inputRef.current?.value) console.log(inputRef.current?.style) }, []); -
通过ref来修改DOM属性值
function App() {
const inputRef = useRef<HTMLInputElement>(null);
function changeInputVal() {
if (inputRef.current) {
inputRef.current.value = "50"
}
}
return <>
<input ref={inputRef} type="text" defaultValue="20"/>
<button onClick={changeInputVal}>改变</button>
</>
}
- 使用ref绑定自定义组件 (高阶组件)
- 需要使用一个新的Hook useImperativeHandle 和 react forwardRef 方法
- useImperativeHandle 是官方为了简化ref操作,让子组件暴露出方法和状态给父组件调用, useImperativeHandle是用在子组件上的,同时还需要搭配forwardRef使用
- forwardRef接受一个渲染函数,使用该函数来决定为 ref 转发组件显示的内容,详细解说之后再讲解,简单来说就是转发
interface GameProps { title: string value: string | number } interface GameAttr { value?: string open: Function } const GameCom = forwardRef<GameAttr, GameProps>(({ title, value }, ref) => { function message() { alert("game组件的message 方法") } useImperativeHandle(ref, () => ({ open: message })); return <span> <h3>{title}</h3> <input type="text" defaultValue={value}/> </span> })- GameProps 是该组件需要的属性
- GameAttr 是该组件暴露给父组件的方法和状态
- { title, value } 就是结构后的 Props
- 父组件中调用
function App() {
const gameRef = useRef<GameAttr>(null);
return <>
<ul>
<li>
<GameCom ref={gameRef} title="游戏组件" value="game001"></GameCom>
<button onClick={() => gameRef.current?.open()}>按钮{gameRef.current?.value}</button>
</li>
</ul>
</>
}
ref={gameRef}来绑定子组件title="游戏组件" value="game001"传入必须的属性- 通过gameRef实例来获取子组件暴露的状态和方法
3. 总结
- 学习了通过useRef 获取到DOM元素
- 创建高阶自定义组件,并暴露出状态和方法