- Hook,使用在函数组件中
- 不要在循环,条件或嵌套函数中(if、switch、for)调用 Hook
1. 函数指向相同的引用
- 更新方式:函数组件中state变化时才重新渲染(React使用Object.is比较算法来比较state);
- 而类组件每次都会更新
2.强制刷新
- 函数组件
import { useState } from 'react'
window.arr = []
// create react app是基于webpack(模块化打包工具),如果用var声明arr,arr只是在当前文件夹,并不是在全局
// 要想在全局访问arr需要添加到window上
export default function App(props) {const [, setCount] = useState({});window.arr.push(setCount)console.log('全局的arr', window.arr)return (<><button onClick={() => setCount({})}>click</button></>)
}
- 类组件中,this.setState传任何值都会刷新组件
- 类组件中可以用
this.forceUpdate()
强制刷新,不会经过shouldComponentUpdate
生命周期
3. 函数更新和不同的返回值的更新
import { useState } from 'react'
window.arr = []
// create react app是基于webpack(模块化打包工具),如果用var声明arr,arr只是在当前文件夹,并不是在全局
// 要想在全局访问arr需要添加到window上
export default function App(props) {const [count, setCount] = useState(+0);window.arr.push(setCount)console.log('全局的arr', window.arr)const onClick = () => {setCount(count + 1)console.log('初始状态', count) // 第一次点击:打印0(上一次的值而不是最新的返回值)setCount(count + 1) // 因此,即使在这里执行多次,更新后count都为1}console.log('最新状态', count) // 第一次点击:打印1return (<><h1>{count}</h1><button onClick={onClick}>click</button></>)
}
import { useState } from 'react'
export default function App(props) {const [count, setCount] = useState(+0);const onClick = () => {setCount(count => count + 1) // 闭包,用最新的count进行更新setCount(count => count + 1)console.log('初始状态', count) // 第一次点击:打印0(上一次的值而不是最新的返回值)}console.log('最新状态', count) // 第一次点击:打印2 (点击时递增了2次)return (<><h1>{count}</h1><button onClick={onClick}>click</button></>)
}
4. setCount是会合并的
- 多个setCount则执行多次,但最终只render一次
- 类组件:返回值合并(state的多个属性合并),函数组件中不会合并,直接用setCount的参数更新了
import { useState } from 'react'
export default function App(props) {const [count, setCount] = useState({ num1: 1 });const onClick = () => {setCount({ new: 2 })}console.log('更新后', count)return (<><h1>{count.num1}</h1><button onClick={onClick}>click</button></>)
}
5. 惰性初始化
initialState
参数只会在组件的初始渲染中起作用,后续渲染时会被忽略。
const [count, setCount] = useState(() => {console.log(1); // 惰性初始化,只会打印一次return 1
});