useState
- 检查 hooks 插件
- eslint-plugin-react-hooks
- 设置默认值
const Foo(props){
const [foo, setFoo] = useState(() => {
return props.foo || 'defaultValue'
})
}
useEffect
- 执行副作用
- 第一个参数为回调,第二个参数为空或者数组。
- 数组为依赖,依赖变化则执行回调(同 useMemo, useCallback, useRef)
useMemo
执行时机与 useEffect 区别
- useEffect 中的回调是在渲染后执行
useMemo 的返回值是要参与渲染,所以其中的回调是在渲染期间执行
useMemo 回调的执行
依赖发生变化一定会触发回调的执行
- 依赖不变化,回调也可能执行
- 所以,不可依赖 useMemo 与 useCallback 触发重新渲染
useRef
- 获取子组件或者 DOM 节点
- 渲染周期之间共享数据的存储
- useRef 不支持函数参数
custom hook
- 以 use 前缀命名
-
hooks 使用原则
只能在顶层调用 hooks
不允许在条件、循环、嵌套函数中调用 hooks,这保证了每次重新渲染 hooks 都是同样的调用顺序
- 只能在函数组件和自定义 hooks 中调用 hooks
类组件迁移函数组件
生命周期函数如何映射至 hooks
替代类组件中的 getDerivedStateFromProps 生命周期函数
class Counter extends React.Component{
state = {overflow: false}
static getDerivedStateFrmProps(props, state){
if (props.count > 10) return {
overflow: true
}
}
}
function Counter(props){
const [overflow, setOverflow] = useState(false)
if (props.count > 10) setOverflow(true)
}
替代最常用的 componentDidMount componentWillUnmount componentDidUpdate
function App(){
useEffect(() => {
// componentDidMount
return () => {
// componentWillUnmount
}
}, [])
const renderCount = useRef(0)
renderCount.current++
useEffect(() => {
if (renderCount > 1){
// componentDidUpdate
}
})
}
getDerievedStateFromError componentDidCatch getSnapshotBeforeUpdate
- 暂时无法替代
类实例成员变量如何映射至 hooks
- 使用 useRef,useRef 不支持函数参数
hooks 中如何获取历史 props 与 state
function Counter(props){
const [count, setCount] = useState(0)
const prevCountRef = useRef()
useEffect(() => {
prevCount.current = count
})
const prevCount = prevCountRef.current
return (
<div>
count: {count} prevCount: {prevCount}
<button onClick={setCount(count+1)}>add</button>
</div>
)
}
如何强制更新一个 hooks 组件
function App(){
const [, setUpate] = state(0)
const forceUpdate = () => {
setUpate(n => n + 1)
}
}