Hook 是 React 16.8.0 增加的新特性,让我们能在函数式组件中使用
state和其他特性
(1)State Hook让函数式组件也可可以有state状态,并进行状态数据的读写(2)语法:
const [xxx, setXxx] = React.useState(initValue)
initValue为状态初始化值,第一次初始化指定的值在内部做缓存- 返回值
xxx, setXxx,包含 2 个元素的数组,分别为当前状态值和状态更新函数
(3)setXxx()的 2 种用法:
setXxx(newValue)参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值setXxx(value => newValue)参数为函数,接受原本的状态值,返回新的状态值,内部用其覆盖原来的状态值注意!若有多个状态,只能多次调用
React.useState,不能使用对象!
点我加1 案例:
import { useState } from "react"; export default function Demo(props) { const [count, setCount] = useState("0") function addOne { setCount(count + 1) #第一种写法 # setCount(count=>count+1) #第二种写法 } return ( <div> <h2>求和为{count}</h2> <button onClick={addOne}>点我加1</button> </div> ) }(1) 点击button ,会调用addOne函数,然后调用更新状态函数,然后Demo函数式组件重新执行渲染,这会导致const [count, setCount] = useState("0") 这句代码执行,每次点击button都会让执行此句代码。react底层做了处理,不会因为每次更新都执行这句代码导致重新初始化状态。而是保留上次的状态值。
(2)()=>{} 箭头函数 如果单个参数,可以省略括号,如果就一行返回值代码,可以省略return。如果返回的是对象 需要写小括号({}),防止和代码段的{}混淆。
Effect Hook让我们能在函数式组件中执行副作用操作(就是模拟生命周期钩子)- 副作用操作:发送 Ajax 请求、定时器、手动更改真实 DOM
Effect Hook可以模拟三个钩子:componentDidMount、componentDidUpdate、componentWillUnmountReact.useEffect第一个参数return的函数相当于componentWillUnmount,若有多个会按顺序执行
// 语法 React.useEffect(() => { ... return () => { // 组件卸载前执行,即 componentWillUnmount 钩子 ... } }, [stateValue]) // 模拟 componentDidMount // 第二个参数数组为空,表示不监听任何状态的更新 // 因此只有页面首次渲染会执行输出 React.useEffect(() => { console.log('DidMount') return () => { console.log('WillUnmount 1') } }, []) // 模拟全部状态 componentDidUpdate // 若第二个参数不写,表示监听所有状态的更新 React.useEffect(() => { console.log('All DidUpdate') return () => { console.log('WillUnmount 2') } }) // 模拟部分状态 componentDidUpdate // 第二个参数数组写上状态,表示只监听这些状态的更新 React.useEffect(() => { console.log('Part DidUpdate') return () => { console.log('WillUnmount 3') } }, [count, name]) // 若调用 ReactDOM.unmountComponentAtNode(document.getElementById('root')) // 会输出 WillUnmount 1、2、3
Ref Hook可以在函数式组件存储或查找组件内的标签或其他数据- 语法:
const refContainer = React.useRef()- 保存标签对象的容器,和
React.createRef()类似,也是专人专用
function Demo() { const myRef = React.useRef() function show() { console.log(myRef.current.value) } return ( <div> <input type="text" ref={myRef} /> <button onClick={show}>展示数据</button> </div> ) }