众所周知react函数组件中是没有生命周期和state的概念的,那我们在使用函数组件的时候该如何管理组件的状态,以及使用组件的生命周期呢?react在16.8版本推出了hooks的概念,既是为了让函数组件也能管理状态,和执行生命周期钩子函数了。
1.useState的使用
useState是最常用的hooks之一了,可是使用它来为函数组件添加一个状态
const app = ()=>{
const [count, setCount] = useState(0);
return <div>{count}</div>
}
上面的代码就是为app组件添加了一个count状态,useState的参数代表count的初始值,那么怎么去改变count的值,从而该改变页面上显示的数字呢?
const app = ()=>{
const [count, setCount] = useState(0);
return (<div onClick(()=>{
setCount(1)
}
</div>)>{count}</div>)
}
上边的代码为div添加了onClick事件,挡点击div时就会执行setCount函数,setCount函数是useState()返回的数组的第二个元素,就是用来改变count的值的,也就是说执行setCount后会改变count的值,同时重新渲染页面。
useState()函数的作用就是返一个数组,数组的第一个元素是一个可以用来表示状态的变量,第二个元素是一个函数,执行这个函数并传递一个参数就可以将参数赋值给状态,并重新渲染组件。
2.useEffect的使用
useState是为了让函数组件有状态管理的功能,那生命周期要怎么实现呢?
const app = ()=>{
const [userName, setUserName] = useState(undefined);
useEffect(()=>{
getUserInfo().then((res)=>{
setUserName(res.data.userName)
})
}, []);
return (
<div>{userName}</div>
)
}
上面的代码使用了useEffect(),会在app组件在渲染前就执行getUserInfo()函数,发送异步请求,拿到userInfo,其实就相当于类组件的componentDidMonunt()生命周期。
useEffect主要有三种用法,分别对应第二个参数的三种形式
1.不传递第二个参数
const app = ()=>{
const [count, setCount] = useState(0);
const [num, setNum] = useState(0);
useEffect(()=>{
console.log(count);
});
return (
<div onClick={()=>{
setCount(count+1)
}}>{count}</div>
)
}
每当点击div执行setCount()时,组件刷新,就会执行useEffect的函数。
2.当第二个参数为数组[num]时,
useEffect()的第二个参数为空时,组件每次更新都会执行useEffect(),当第二个参数为数组时,只有当数组中的元素被更新后,才会执行useEffect(),
const app = ()={
const [count, setCount] = useState(0);
const [num, setNum] = useState(0);
useEffect(()=>{
setNum(count)
}, [count]);
return (
<div>
<div onClick={()=>{
setCount(count+1)
}}>{count}</div>
<div>{num}</div>
</div>
)
}
当点击count时,会更新count的值,同时会执行useEffect(),所以num的值也会发生变化。
3.当第二个参数为空数组时
当我们只想在组件第一次渲染时,执行的操作,可以放在第二个参数为空的useEffect()函数中,比如网页初始化时发送的异步请求。
const app = ()=>{
useEffect(()=>{
getUserInfo().then((res)=>{
setUserName(res.data.userName)
})
}, []);
}
3.useRef()的使用
当你想保存一个可以变化的值,但又不希望这个值的变化引起组件重新'render'时,可以使用useRef()
import React, { useRef } from "react";
const Demo = () => {
const countRef = useRef(1);
return (
<div
style={{ width: "500px", height: "500px", backgroundColor: "#e5e5e5" }}
>
<span> countRef: </span> <span>{countRef.current}</span>
<button
onClick={() => {
countRef.current++;
}}
>
add
</button>
<button
onClick={() => {
alert(countRef.current);
}}
>
show countRef
</button>
</div>
);
};
上述代码的功能很简单,使用useref存储了一个变量countRef,点击一次add按钮,countRef便自增一次,但页面上展示countRef的地方确并没有出现任何变化,然而实际上countRef的值是发生了变化的,怎么证明呢?我们再次点击show countRef按钮,浏览器就会弹出当前countRef的值。