在react中,hooks 就是把某个目标结果钩到某个可能会变化的数据源或者事件源上,那么当被钩到的数据或事件发生变化时,产生这个目标结果的代码会重新执行,产生更新后的结果。
hooks的好处:
- 逻辑的复用
- 有助于关注分离
hooks 的使用规则:
- 只能在函数组件的顶级作用域使用。hooks不能在循环、条件判断或者嵌套函数内执行,而必须是在顶层。同时hooks在组件的多次渲染之间,必须按顺序被执行。
- 只能在函数组件或者其他hooks中使用
useState 让函数组件具有维持状态的能力
export default function Example() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => { setCount(count + 1); }} >
{count}
</button>
</div>
);
}
- useState(initialState)的参数是创建state的初始值,它可以是任意类型
- useState的返回值是有两个元素的数值,第一个值用来读取,第二个用来设置
- 如果要创建多个state,就要多次调用useState
- state中永远不要保存可以通过计算得到的值,比如说从props、url、cookie、localStorage中,用的时候读,而不是读了之后存到state里面
useEffect 执行副作用
useEffect(effect: EffectCallback, deps?: DependencyList)
useEffect(() => {
effect
return () => {
cleanup
}
}, [input])
useEffect第一个参数表示要执行的函数,第二个是可选的依赖项数组。useEffect让我们能够在下面四种时机去执行一个回调函数产生副作用:
- 每次render后执行:不提供第二个依赖项参数。比如:
useEffect(() => { })
- 仅第一次render后执行:提供一个空数组作为依赖项。比如
useEffect(() => { }, [])
- 第一次以及依赖项发生变化后执行:提供依赖项数组。比如
useEffect(() => { }, [...deps])
- 组件unMount后执行:返回一个回调函数。比如
useEffect(() => { return () => { } }, [])
useCallback 缓存回调函数
useCallback(fn, deps)
export default function Example() {
const [count, setCount] = useState(0);
const handleChange = () => {
setCount(count + 1);
}
return (
<div>
<button onClick={handleChange} >
{count}
</button>
</div>
);
}
在react函数组件中,每一次UI的变化,都是通过执行整个函数来完成的,这意味着每次渲染都会新建一个handleChange
,创建一个新的事件函数,不会影响结果正确性,但这不仅会增加系统开销,还会让接受事件处理函数的组件重新渲染。
export default function Example() {
const [count, setCount] = useState(0);
const handleChange = useCallback(() => {
setCount(count + 1);
}, [count]) // 只有当 count 发生变化时,才会重新创建回调函数
return (
<div>
<button onClick={handleChange} >
{count}
</button>
</div>
);
}
useMemo 缓存计算的结果
useMemo(fn, deps)
如果某个数据是通过其他数据计算得到的,那么只有当用到的数据,也就是依赖的数据发生变化的时候,才应该重新计算。它可以避免子组件的重复渲染
const getTotal = useMemo(() => {
return () => (<span>已经选中{keys.length}项</span>)
}, [keys])
useRef 在多次渲染之间共享数据
const ref = useRef(initalValue)
它有两个功能:
- 在多次渲染之间共享数据
- 保存某个DOM节点的引用
useContext 定义全局状态
const MyContext = React.createContext(initValue)
const value = useContext(myContext)
<MyContext.Provider >
</MyContext.Provider>
useReducer
reducer是一个函数(state, action) => newState
see 彻底搞定 useReducer