React Hooks
useEffect
- 页面初始化
useEffect会执行 return 前面的代码。 - 然后页面的任何数据更新了,组件就会重新渲染,就是先把原来的组件卸载,然后重新渲染更新的组件。
- 如下代码,初始化打印
effect invoked,更新页面先打印effect deteched,然后打印effect invoked(因为更新的时候相当于先把原先的组件销毁再重新渲染新的组件)。 useEffect里面第二个参数是个数组 [],这个数组里面放useEffect用到的外面的数据(依赖)。然后useEffect就会根据数组里面的数据来判断要不要重新执行。只有写在里面的数据发生改变的时候,useEffect才会重新执行。如果是个空数组,则只会执行一次,如果不填第二个参数,则不管啥数据改变了,useEffect都会执行。
js
useEffect(() => {
console.log('Effect invoked');
// 组件卸载的时候执行 return 的函数
return () => console.log('Effect deteched');
}, []);useLayoutEffect 与 useEffect 的区别
useLayoutEffect比useEffect先执行。useLayoutEffect是在页面更新时DOM树渲染成HTML之前执行的useEffect是在页面更新时DOM树渲染成 HTML 之后执行的- 所以很少用
useLayoutEffect,因为如果useLayoutEffect执行时间过长,页面渲染就会等待,造成页面卡顿,降低用户体验。
react hooks 初识
- useState 和 自定义 hook。(自定义 hook 必须以 use 开头)
typescript
import React, { useState, useEffect } from 'react';
import useMousePosition from '../hooks/useMousePosition'; //自定义 Hooks
const LikeButton: React.FC = () => {
const [like, setlike] = useState(0); //useState
const [on, setOn] = useState(true);
const positions = useMousePosition();
useEffect(() => {
document.title = `点击了${like}次`;
});
return (
<>
<button
onClick={() => {
setlike(like + 1);
}}
>
{like}
</button>
<button
onClick={() => {
setOn(!on);
}}
>
{on ? 'on' : 'off'}
</button>
<h1>
X: {positions.x}, Y : {positions.y}
</h1>
</>
);
};
export default LikeButton;Capture Value
- Capture Value 是一个在 React 中老生常谈的问题,下面结合一个小 Demo 学习它。来源
js
function Counter() {
const [count, setCount] = useState(0);
function handleAlertClick() {
setTimeout(() => {
alert('You clicked on: ' + count);
}, 3000);
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
<button onClick={handleAlertClick}>Show alert</button>
</div>
);
}然后按如下步骤操作:
- 1)点击 Click me 按钮,把数字增加到 3。
- 2)点击 Show alert 按钮。
- 3)在 setTimeout 触发之前点击 Click me,把数字增加到 5。
最后 Alert 的结果是 3!我们能得出以下结论。
- 每次渲染相互独立,因此每次渲染时组件中的状态、事件处理函数等等都是独立的,或者说只属于所在的那一次渲染。
- 我们在 count 为 3 的时候触发了 handleAlertClick 函数,这个函数所记住的 count 也为 3。
- 三秒种后,刚才函数的 setTimeout 结束,输出当时记住的结果:3。
解决办法:
可以使用 useRef 这个 Hooks 来解决这个问题。
russ