之前的函数式组件由于没有自己的this,导致其不能使用state、refs、生命周期等,只能定义简单的组件。React16.8版本新增了hooks、使得函数式组件也可以使用这些特性,扩展了它的可用性。
一、State Hook
State Hook 让函数组件也拥有state状态,进行数据的读写操作。
实现点击按钮,sum值加1:
import React from "react";
function Demo() {
const [sum, updateSum] = React.useState(0);
function add() {
// updateSum(sum+1); // 第一种写法
updateSum(sum => sum+1); // 第二种写法
}
return (
<div>
<h2>当前求和为{sum}</h2>
<button onClick={add}>点我+1</button>
</div>
)
}
export default Demo;
语法:
-
const { newVal,setValue } = useState(initValue);
(1)useState的参数为初始值。它会底层被缓存;
(2)返回值为包含两个元素的数组。第一个为当前值,第二个为修改该值的方法; -
setValue函数的参数有2种写法:
(1)参数不是函数,直接替换掉原value;
(2)参数为函数,接受之前的状态值,返回新的状态值。
二、 Effect Hook
可以通过Effect Hook 模拟常用的生命周期钩子的功能。
import React from "react";
function Demo() {
const [sum, updateSum] = React.useState(0);
React.useEffect(()=> {
console.log('useEffect'); // 传入[],只打印1次
}, [])
function add() {
updateSum(sum+1);
}
return (
<div>
<h2>当前求和为{sum}</h2>
<button onClick={add}>点我+1</button>
</div>
)
}
export default Demo;
实现每隔一秒,sum值自增1,并在组件卸载之前清除定时器:
function Demo() {
const [sum, updateSum] = React.useState(0);
React.useEffect(()=> {
setInterval(()=> {
updateSum(sum => sum+1); // 注意这里必须传回调,如果传入值,不会基于上次改变后的值改变
}, 1000);
}, [])
return (
<div>
<h2>当前求和为{sum}</h2>
</div>
)
}
语法:
-
useEffect接受两个参数:
第一个参数:
(1)可以写入方法体,会在特定时候被调用;
(2)可以return一个回调,在组件卸载时执行,相当于willUnmount钩子。
第二个参数:
(1)传入[],则该钩子类似于didMount钩子,只在组件初始挂载时调用一次回调;
(2)传入[value1, value2],则只有初始挂载和数组中的value值更新时,会调用回调;
(3)不传,相当于传入所有状态值,在初始挂载和render时都会调用。 - 常用来发请求、创建、销毁定时器等操作。
三、Ref Hook
useRef实现了createRef的功能。
点击按钮,提示输入框中的内容:
function Demo() {
const inputRef = React.useRef();
function show() {
alert(inputRef.current.value);
}
return (
<div>
<input type="text" ref={inputRef}/>
<button onClick={show}>点我展示数据</button>
</div>
)
}
语法:
-
const refContainer = React.useRef(),通过refContainer.current.value取值;