Hook是React 16.8.0版本新增的新特性、新语法。为什么标题讲的是Hooks,而这里我写的是Hook呢,是因为Hook一共有三种,他们分别实现了不同的功能,从而可以将函数式组件中使用React的一些特性,例如:state、setState、生命周期钩子、ref绑定数据。
这些Hook分别为:State Hook、Effect Hook、Ref Hook
一、State Hook
1. State Hook可以让函数式组件有state状态,并进行状态数据的读写操作
2. 语法:const [xxx,setXxx] = React.useState(initValue)
3. useState()说明:
参数:第一次初始化指定的值在内部做缓存
返回值: 包含2个元素的数组,第一个为内部当前状态值,第二个为更新状态值的函数
4. setXxx() 两种写法:
1. setXxx(newValue): 参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值
2. setXxx(value=>newValue): 参数为函数,接收原本的状态值,返回新的状态值,内部用其覆盖原来的状态值。
function Item() {
const [count,setCount] = React.useState(1)
function add(){
//第一种setCount的写法
setCount(count+1)
//第二种setCount的写法
// setCount(count=>count*2)
}
return(
<div>
<h2>当前页面的count值为:{count}</h2>
<button onClick={add}>点击+1</button>
</div>
)
}
二、Effect Hook
1. 可以让函数式组件具有生命周期钩子
2. 用法:React.useEffect(()=>{
//在此可以执行任何带副作用的操作
return ()=>{
//在此做一些收尾工作,比如清除定时器,取消订阅等等,这些相当于 componentWillUnmount()
}
},[])
参数:可以传一个参数,也可以传两个参数
如果只传了一个参数,则每当state中数据发生改变,react底层都会重新执行第一个参数的函数体。
如果传了第二个参数,并且是个空数组,则Effect只会执行一次,不监听任何state值得变化。
如果第二个参数数组中添加了一些state值,则Effect会监听这些state值得变化,一旦其中某个state值发生了改变,就会执行第一个参数函数体。
3. 总结:
如果在第二个参数中传了空数组,则Effect相当于componentDidMount钩子,只会在组件加载时执行一次。如果不写第二个参数,则组件第一次加载相当于componentDidMount,后面会监听全部state值得改变,此时又相当于componentDidUpdate;如果传的参数,包含了某些state数据,则只会监听这些数据的变化。
function Item() {
const [count,setCount] = React.useState(1)
function add(){
// setCount(count+1)
setCount(count=>count*2)
}
React.useEffect(()=>{
const timer = setInterval(()=>{
setCount(count+1)
},1000)
return ()=>{
clearInterval(timer)
}
}) //在此是没有写第二个参数,所以会监听所有state中的值
//所以count值为每秒加一并渲染到界面上
return(
<div>
<h2>当前页面的count值为:{count}</h2>
<button onClick={add}>点击+1</button>
</div>
)
}
function Item() {
const [count,setCount] = React.useState(1)
function add(){
// setCount(count+1)
setCount(count=>count*2)
}
React.useEffect(()=>{
const timer = setInterval(()=>{
setCount(count+1)
},1000)
return ()=>{
clearInterval(timer)
}
},[]) //这种加了第二个参数,空数组,并没有监听任何状态值,所以count值只会在页面初次渲染时加一,之后不会因为有个定时器的存在,而每秒加一学渲染到界面
return(
<div>
<h2>当前页面的count值为:{count}</h2>
<button onClick={add}>点击+1</button>
</div>
)
}
function Item() {
const [count,setCount] = React.useState(1)
const [name,setName] = React.useState('小聂')
function add(){
// setCount(count+1)
setCount(count=>count*2)
}
function changeName(){
setName('小王')
}
React.useEffect(()=>{
const timer = setInterval(()=>{
setCount(count+1)
},1000)
console.log('我监听到了名字的变化')
return ()=>{
clearInterval(timer)
}
},[name])
return(
<div>
<h2>当前页面的count值为:{count}</h2>
<button onClick={add}>点击+1</button>
<h2>我的名字是:{name}</h2>
<button onClick={changeName}>点击改名</button>
</div>
)
}
三、Ref Hook
在类式组件中,我们使用ref绑定数据,首先需要创建ref =====>createRef()
示例: myRef = React.createRef()
< input type=“text” ref={this.myRef} />
函数式组件中,需要使用useRef,示例:
const myRef = React.useRef()
< input type=“text” ref={myRef} />
class Item extends React.Component {
myRef = React.createRef()
getValue = (e) => {
if(e.which!==13) return
alert(this.myRef.current.value)
}
render() {
return (
<div>
<input type="text" onKeyPress={this.getValue} ref={this.myRef}/>
</div>
);
}
}
function Item() {
const myRef = React.useRef()
function getValue(e){
if(e.which!==13) return
alert(myRef.current.value)
}
return(
<div>
<input onKeyPress={getValue} type="text" ref={myRef}/>
</div>
)
}