React Hook/Hooks是什么?
1 Hook是react 16.8版本增加的新特性/新语法
2 因为函数式组件没有this,使用hooks可以让函数式组件使用 state 以及其他的react 特性(比如生命周期钩子)
常见的Hook
(1) state Hook:React.useState()
(2) Effect Hook: React.useEffect()
(3) Ref Hook: React.useRef()
(4) Context Hook: React.useContext()
1. state Hook
- 让函数组件也可以有state状态,并进行状态数据的读写操作
- 语法:const [ xxx, setxxx] = React.useState(inintValue)
- useState()说明:
参数:第一次初始化指定的值在内部作缓存,也就是虽然函数组件调用多次,初始值initValue只传一次,之后将解构出的状态作缓存
返回值:包含2个元素的数组。第一个为内部当前状态,第二个为更新状态值的函数
- setxxx() 两种写法
(1)setxxx(newValue):参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值
(2)setxxx(value => newValue) :参数为函数,接收原本的状态值,内部用其覆盖原来的状态值
案例:
function Demo() {
// 调用useState() 当有多个状态时需要写多次useState
const [count, setCount] = React.useState(0)
const [username, setName] = React.useState('张三')
// 点击事件回调
function add() {
setState(count => count+1)
}
function changeName() {
setState('李四')
}
return (
<div>
<h1>当前和为:{count}</h1>
<h1>当前用户为:{userName}</h1>
<button onclick={add}>点击+1</button>
<button onclick={changeName}>切换用户</button>
</div>
)
}
2. Effect Hook
- Effect Hook 可以让函数组件中执行副作用操作(类似类组件生命周期)
- react中副作用操作;
发ajax请求获取数据
设置订阅、启动定时器
手动更改真实DOM
- 语法:
React.useEffect(()=>{
// 在此可以写附带作用操作
let timer = setTimeout(() => {
setCount(count => count+1)
}, 1000)
return() =>{ // 组件将要卸载前执行
// 此处做一些收尾工作,如清除定时器、取消订阅等
clearInterval(timer)
}
},[])
(1)useEffect()传 两个参数 第一个参数为函数 若函数中返回函数 这个返回的函数相当于执行componentWillUnmount(){}钩子,没有返回则不执行componentWillUnmount(){}钩子
(2) 当第二个参数不传,则相当于监听所有状态 相当于执行生命周期 componentDidMount(){}钩子和componentDidUpdate(){}钩子
(3)当第二个参数传[],则相当于什么也不监听 此时第一个参数相当于执行生命周期 componentDidMount(){}狗子
(4)当第二个参数传[XXX],则相当只监听XXX状态 只要XXX状态改变此时第一个参数相当于执行生命周期 componentDidMount(){}钩子和componentDidUpdate(){}钩子 ,若其余状态改变 不用执行componentDidUpdate(){}钩子
案例
案例场景:当页面一加载和每秒自增,点击卸载按钮卸载组件清空定时器
function Demo() {
const [count, setCount] = React.useState(0)
React.useEffect(()=>{
// 在此可以写附带作用操作
let timer = setTimeout(() => {
setCount(count => count+1)
}, 1000)
return() =>{ // 组件将要卸载前执行
// 此处做一些收尾工作,如清除定时器、取消订阅等
clearInterval(timer)
}
},[])
// 卸载组件回调
function unmount() {
// ReactDom.unmountComponentAtNode() 此方法为模拟卸载组件场景,用之前须引入 impont ReactDom from 'react-dom'
ReactDom.unmountComponentAtNode(document.getElementById('root'))
}
return (
<div>
<h1>当前和为:{count}</h1>
<button onclick={unmount}>卸载组件</button>
</div>
)
}
3. Ref Hook
- Ref Hook可以在函数组件中存储/查找组件内的标签或任意其他数据
- 语法:const myRef = React.useRef()
- 作用:保存标签对象,功能与类组件中React.createRef()一样
案例
function Demo() {
const myRef = React.useRef()
// 提示按钮回调
function add() {
alert(myRef.current.value)
}
return (
<div>
<input type="text" ref={myRef} />
<button onclick={showValue}>提示输入框内容</button>
</div>
)
}
4. Context Hook
useContext()是用来处理多层级传递数据的方式。其主要用于解决函数组件之间传值的问题
步骤:
1. 首先要进行导入createContext,useContext
2. 在子组件中使用useContext进行接收父组件传递的上下文
3. 创建一个上下文全局变量
4. 在父组件将值传递过去,Provider 相当于提供者
案例
// 首先要进行导入createContext,useContext
import React,{useState,createContext,useContext} from 'react'
function Child(){
//在子组件中使用useContext进行接收父组件传递的上下文,这样值就能传递过来了
const count1=useContext(CountContext)
return (
<h1>{count1}</h1>
)
}
// 创建一个上下文全局变量
const CountContext=createContext()
function Example3(){
const [count,setCount]=useState(0)
function handleClick(){
setCount(count+1)
}
return (
<div>
点击{count}
<button onClick={handleClick}>clickme</button>
// 其次是作为父组件将值传递过去,Provider 相当于提供者,Child是子组件
<CountContext.Provider value={count}>
<Child></Child>
</CountContext.Provider>
</div>
)
}
export default Example3
还有更多hook 有待后期补充