useRef
- useRef 返回一个可变的 ref 对象,其
.current
属性被初始化为传入的参数(initialValue)
- 返回的 ref 对象在组件的整个生命周期内保持不变
forwardRef
- 将ref从父组件中转发到子组件中的dom元素上
- 子组件接受props和ref作为参数
useImperativeHandle
-
useImperativeHandle
可以让你在使用 ref 时自定义暴露给父组件的实例值
- 在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用
- 其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect
- 可以使用它来读取 DOM 布局并同步触发重渲染
- 在浏览器执行绘制之前useLayoutEffect内部的更新计划将被同步刷新
- 尽可能使用标准的 useEffect 以避免阻塞视图更新
import React, { useEffect, useState, useRef, forwardRef, useImperativeHandle, useLayoutEffect } from 'react';
//useEffect的销毁
function Counter1() {
let [state, setState] = useState({ number: 0 });
//useEffect里面方法会有返回值,返回值是一个函数,一般用来执行清理动作
//每次执行effect之前都会执行此unEffect函数
useEffect(() => {
let $timer = setInterval(() => {
setState(prevState => ({ number: prevState.number + 1 }));
}, 1000);
return () => {
clearInterval($timer);
}
}, []);
return (
<div>
<p>{state.number}</p>
<button onClick={() => setState(prevState => ({ number: prevState.number + 1 }))}>+</button>
</div>
)
}
//一定是第个参数
function Child(props, parentRef) {
let inputRef = useRef();
useImperativeHandle(parentRef, () => (
{
focus() {
inputRef.current.focus();
},
setValue(newVal) {
inputRef.current.value = newVal;
}
}
));
return (
<>
<input type="text" ref={inputRef} />
</>
)
}
let ForwardedChild = forwardRef(Child);
function Parent() {
let [number, setNumber] = useState(0);
let parentRef = useRef();//{current:null} //每次都会返回同一个对象
function getFocus() {
//希望在父组件只能调用focus方法,其它的方法都不能调用
parentRef.current.focus();//current是此input框 的真实DOM元素
//inputRef.current.value = 'something';
parentRef.current.setValue('something');
}
return (
<>
<ForwardedChild ref={parentRef} />
<button onClick={() => setNumber(prevState => prevState + 1)}>+</button>
<button onClick={getFocus}>获得焦点</button>
</>
)
}
function Counter3() {
let [color, setColor] = useState('red');
useLayoutEffect(() => {
console.log("useLayoutEffect", document.getElementById('myDiv').style.backgroundColor);
alert('useLayoutEffect' + color);
});
useEffect(() => {
console.log("useEffect", document.getElementById('myDiv').style.backgroundColor);
alert('useEffect' + color);
});
return (
<>
<div id="myDiv" style={{ backgroundColor: color }}>颜色</div>
<button onClick={() => setColor('red')}>红</button>
<button onClick={() => setColor('yellow')}>黄</button>
<button onClick={() => setColor('blue')}>蓝</button>
</>
)
}
export default Counter3;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。