hook 规则
- 1.hook 不要在循环, 条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层以及任何 return 之前调用他们
- 2.hook 只能在函数组件里调用 (包括自定义 hook), 不能用在 普通函数 或者 类组件里
- 3.hook 为什么必须要放到最顶层 因为hook 必须按照一定的顺序执行, (举个例子) 否则就会报错, 所以必须放在最顶层
useState简单演示
import React, { useState } from 'react';
function Example() {
// 声明一个新的叫做 “count” 的 state 变量 const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useImperativeHandle 的使用
-
正常情况下 ref 是不能挂在到函数组件上的,因为函数组件没有实例,但是 useImperativeHandle 为我们提供了一个类似实例的东西。它帮助我们通过 useImperativeHandle 的第 2 个参数,所返回的对象的内容挂载到 父组件的 ref.current 上。
-
forwardRef会创建一个React组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。
父组件----↓
import React, { useRef, useEffect } from 'react';
import A from './components/A';
function Details() {
const ref = useRef();
useEffect(() => {
console.log(ref, 'ref');
ref.current.fn();
});
return (
<div>
1
<A ref={ref} />
</div>
);
}
export default Details;
子组件----↓
import React, { useImperativeHandle, forwardRef } from 'react';
function A(props, ref) {
const fn = () => {
console.log('我是子组件');
};
useImperativeHandle(ref, () => ({
fn,
}));
return <div>我是子组件</div>;
}
export default forwardRef(A);
最后结果打印出了我是子组件
useEffect 可以模拟哪些生命周期
- componentDidMount // 加载完成的
- componentDidUpdate // 更新阶段
- componentWillUnmount // 卸载阶段
useRef 和 createRef 区别
- useRef 只执行一次,有初始值,可以用于保存上一次的值
- createRef 每次组件渲染都会执行,没有初始值
setInterval, setTimeout 特性
const [time, setTime] = useState(3)
useEffect(() => {
// setInterval, setTimeout 会形成闭包,会保存 time 的复制值,该值与外面的 time
// 不是同一个值
setInterval(() => {
setTime(time - 1)
// 始终输出 3
console.log(time, 'xxx');
}, 1000)
}, [])