如果你在编写函数组件并意识到需要向其添加⼀一些 state,以前的做法是必须
将其它转化为 class。现在你可以在现有的函数组件中使⽤用 Hook
前面的文字写的比较详细,https://blog.csdn.net/qq_28483283/article/details/108123558
这里简单总结一下:
其类似于class组件中的state,用来获取和改变当前页面中的值
const [count, setCount] = useState(0);
其中0表示count的初始值
setCount表示你需要改变的count值
count表示当前count的值是什么
在代码中也是直接{count}即可获取
useEffect类似于class组件中的生命周期函数,useEffect可以代替class组件中的三个生命周期,分别是componentDidMount组件渲染执行函数、componentDidUpdate组件更新执行的函数、componentWillUnmount组件销毁执行时函数
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
useEffect是一个方法,其中有两个参数,一个是一个方法,表示你要执行的动作,另一个是依赖项。表示什么时候更新
这里document.title = You clicked ${count} times
;表示你要执行的动作。 [count]表示在count的值发生变化的时候,useEffect中的方法再执行一次,类似componentDidUpdate函数。
如果useEffect中第二个参数不填,表示只在组件第一次渲染的时候执行,类似于componentDidMount函数
例:
useEffect(() => {
const timer = setInterval(() => {
setDate(new Date());
}, 1000);
return () => clearInterval(timer);
}, []);
那么上面的时钟又引发了另一个问题,什么时候清楚timer 定时器,这里引出useEffect的第三个知识点,
return () => clearInterval(timer);表示在组件销毁的时候执行清楚定时器的动作,类似于componentWillUnmount函数
上面两个基本都和组件的生命周期有关,但有时候不要跟生命周期挂钩
例如:
import React, { useState, useMemo } from "react";
export default function UseMemoPage(props) {
const [count, setCount] = useState(0);
//如果不用useMemo
const expensive =() => {
console.log("compute");
let sum = 0;
for (let i = 0; i < count; i++) {
sum += i;
}
return sum;
//只有count变化,这⾥里里才重新执⾏
};
//如果用useMemo
const expensive = useMemo(() => {
console.log("compute");
let sum = 0;
for (let i = 0; i < count; i++) {
sum += i;
}
return sum;
//只有count变化,这里才重新执⾏
}, [count]);
const [value, setValue] = useState("");
return (
UseMemoPage
expensive:{expensive}
{count}
setValue(event.target.value)} />
);
}
如果不使用useMemo,则会出现一种情况,当input 输入框中的内容改变,expensive中就会从新计算(但是这时候不需要expensive从新执行啊,有人会想到用useEffect不就行了,但是useEffect每次渲染完成以后都会执行一次,肯定不对的),我们想要的结果是input的变化与expensive无关,useMemo解决了这个问题,与useEffect有点类似,只有useMemo中的第二个参数[count]发生变化的时候,才会去从新执行expensive方法
与上面的例子类似,当input中的值发生变化的时候,页面会重新渲染,引入的子组件也会被从新计算调用
import React, { useState, useCallback, PureComponent } from "react";
export default function UseCallbackPage(props) {
const [count, setCount] = useState(0);
const addClick = useCallback(() => {
let sum = 0;
for (let i = 0; i < count; i++) {
sum += i;
}
return sum;
}, [count]);
const [value, setValue] = useState("");
return (
UseCallbackPage
{count}
setValue(event.target.value)} />
);
}
class Child extends PureComponent {
render() {
console.log("child render");
const { addClick } = this.props;
return (
Child
);
}}
使用useCallback可以避免这个问题,
更多官方定义的HOOK还需自己多多学习理解
例如:
//⾃自定义hook,命名必须以use开头
function useClock() {
const [date, setDate] = useState(new Date());
useEffect(() => {
console.log("date effect");
//只需要在didMount时候执⾏就可以了了
const timer = setInterval(() => {
setDate(new Date());
}, 1000);
//清除定时器器,类似willUnmount
return () => clearInterval(timer);
}, []);
return date;
}
调用:
{useClock().toLocaleTimeString()}