Hooks 介绍
Hooks 是 Rax 1.0 新增的特性,它可以让函数组件(Function Component)使用状态和生命周期。Rax 在实现上遵循了 React Hooks 的标准。
常用 Hooks
useState
useState 主要用来定义和管理本地状态。在下面的例子里,我们使用了 useState
来实现了一个计数器:
import { createElement, useState } from 'rax'; function Example() { const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
useState
参数是初始 state,会返回一个数组。数组第一个值是 state,第二个值是改变 state 的函数。
上述例子中 count 与 setCount 是一一配对的,count 的值只能通过 setCount 修改。
useEffect
useEffect 的代码在每次渲染后运行,包括第一次渲染:
import { createElement, useState, useEffect } from 'rax'; function Example() { const [count, setCount] = useState(0); // Similar to componentDidMount and componentDidUpdate: useEffect(() => { document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
useEffect
它跟类组件(Class Component)中的 componentDidMount
、componentDidUpdate
和 componentWillUnmount
具有相同的用途,只不过被合并成了一个 API。
Hooks 使用规则
Hooks 就是 JavaScript 函数,但是使用它们会有两个额外的规则:
- 只在函数最顶层调用 Hooks,不要在循环、条件判断或者子函数中调用。
- 只在 Rax 函数组件 和 自定义 Hooks 中调用 Hooks,不要在其他 JavaScript 函数中调用。
自定义 Hooks
通过自定 Hooks 能够将组件逻辑提取到可重用的函数中。
import { createElement, useState, useEffect } from 'rax'; const useDocumentTitle = function(title) { useEffect( () => { document.title = title; }, [title] ); }; function Example() { const [count, setCount] = useState(0); useDocumentTitle(`You clicked ${count} times`) return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
上述示例中 useDocumentTitle 是一个自定义 Hooks,可以在其他组件中执行设定 title 的逻辑。如果函数的名字以 “use
” 开头并调用其他 Hooks,我们就说这是一个自定义 Hooks。
对应类组件的生命周期
至此相信您已经对 Hooks 有了基本的了解。对照 类组件的生命周期,可通过以下 Hooks 实现对应的生命周期:
- useEffect
- componentWillUpdate
- componentDidMount
- componentWillUnmount
- useLayoutEffect
- 与 useEffect 一致,用于获取元素渲染结果
- useMemo、useCallback
- shouldComponentUpdate
使用 useEffect 完成 componentWillUpdate 的效果,示例:
function DemoComponent() { useEffect(() => { // TODO }); return <p>Hello hooks!</p> }
使用 useEffect 可以实现 componentDidMount 的功能,示例:
function DemoComponent() { useEffect(() => { // TODO // useEffect 的第二个参数为[]时,表示这个 effect 只会在 componentDidMount、componentWillUnMount 的时候调用。 }, []); return <p>Hello hooks!</p> }
使用 useEffect 可以实现 componentWillUnmount 的功能,示例:
function DemoComponent({source}) { useEffect(() => { const subscription = source.subscribe(); // TODO return () => { // componentWillUnMount 调用的是第一个参数返回的回调。 subscription.unsubscribe(); }; }, [source]); // 表示 source 改变时就是执行一遍 return <p>Hello hooks!</p> }
使用 memo 可以实现 shouldComponentUpdate 的功能,示例:
function DemoComponent(props) { return <h1>I am {props.name}. hi~</h1>; } memo(DemoComponent, (prevProps, nextProps) => prevProps.name === nextProps.name); // 添加第二个参数来指定采用旧 props 和新 props 的自定义比较函数。如果返回 true,则跳过更新。
更多
更多 Hooks 相关的说明,可以参考以下链接: