react hooks 初步

React Hooks 的意思是,组件尽量写成纯函数,如果需要外部功能和副作用,就用钩子把外部代码”钩”进来。 React Hooks 就是那些钩子。

react 约定, hook 一律使用 use 前缀命名,便于识别
常用 hook

useState()
useContext()
useEffect()
useReducer()
useState

useState()用于为函数组件引入状态(state)。纯函数不能有状态,所以把状态放在钩子里面。

1
2
3
4
function Button() {
const [count, setCount] = useState(0);
return <button onClick={setCount(count + 1)}>+1</button>;
}

useState()接受初始值,返回一个数组,数组第一个是当前状态,第二个是更新状态的函数。

useContext

useContext()用于组件间共享状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 创建一个 context 对象
const ctxDep = {name: '王花花'}
const Ctx = React.creatContext(ctxDep)
// 在组件中使用
function App() {
return (
// 下级组件使用 useContext 获取的值是 ctxDep.name
<Ctx.Provider value={ctxDep.name}>
<Sub />
<Sub2 />
</Ctx.Provider>
)
}
function Sub() {
// useContext 获取的是距离当前组件最近的 <MyContext.Provider> 的 value prop 。
// 此处的就是 ctxDep.name
const name = useContext(Ctx)
return (
<div>name: {name}</div>
)
}
function Sub2() {
const name = useContext(Ctx)
...
}

useEffect

useEffect()用来引入具有副作用的操作,最常见的就是向服务器请求数据。

1
2
3
useEffect(() => {
// Async Action
}, [dependencies]);

useEffect()接受两个参数。第一个是一个函数,操作的代码放在里面(常见的是异步操作)。第二个是一个数组,用于给出 Effect 的依赖项,只要这个数组发生变化,useEffect()就会执行。第二个参数可以省略,这时每次组件渲染时,就会执行 useEffect()。 React 会等待浏览器完成画面渲染之后才会延迟调用 useEffect

useEffect 清除操作

在 useEffect 中返回一个函数去执行清除操作, React 会在组件卸载的时候执行清除操作。React 会在执行当前 effect 之前对上一个 effect 进行清除。

1
2
3
4
5
6
useEffect(() => {
...
return function cleanFun() {
...
}
}, [])

useReducer

useReducers()钩子用来引入 Reducer 功能。升级版 useState

1
const [state, dispatch] = useReducer(reducer, initialState);

useReducer()接受 Reducer 函数和状态的初始值作为参数,返回一个数组。数组的第一个成员是状态的当前值,第二个成员是与其配套的发送 action 的 dispatch 函数。

使用 useReducer()接受的 reducer 形式如(state, action) => newState

惰性初始化

使用 useReducer 的第三个参数来设置初始值

1
2
3
const initialState = 1;
// init 是函数,返回 {count: 1}
const [state, dispatch] = useReducer(reducerCount, initialState, init);

如果 useReducer 的返回值与当前 state 相同,React 将跳过子组件的渲染及副作用的执行。

useMemo

用于性能优化,useMemo 返回一个值。

1
const memoizedValue = useMemo(() => dosomething(a, b), [a, b]);

useMemo 会在渲染期执行,但除了第一次外,只会在依赖项发生改变后才会重新执行。

useCallback

useCallback()返回一个函数, 在依赖值没有发生改变时不触发重新渲染。

1
2
3
4
5
6
// 仅当 count 的值发生改变时,memoCallback 才触发组件重新渲染
function Foo() {
const [count, setCount] = useState(0);
const memoizedHandleClick = useCallback(() => console.log(`点击: ${count}`), [count]);
return <Button onClick={memoizedHandleClick}>Click Me</Button>;
}

useRef

1
2
3
4
5
const refContainer = useRef(initialValue);
return (
// 此时 refContainer.current 指向下面这个 button
<button ref={refContainer}></button>
);

useLayoutEffect

效果 useEffect 相同,但会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。

作者

大下坡

发布于

2019-12-24

更新于

2019-12-24

许可协议