useToggle
分析的源码来自:https://github.com/alibaba/ho...
首先,useToggle用于在两个状态值间切换的 Hook。默认为boolean类型,但不仅仅是boolean,也可根据具体情况传入需要的两个状态,并进行切换;同样功能虽利用useState也可实现,但不如重新实现一个hook来得便利。
基本用法
三个重载
- 第一个重载为boolean之间切换,初始状态默认为false。此时defaultValue为初始状态(true或false),reverseValue为另一个值。
- 第二个重载传入一个参数defaultValue,此时reverseValue为!defaultValue。
- 第三个重载传入两个参数,defaultValue和reverseValue。
四个方法
- setLeft:state修改为defaultValue。
- setRight:state修改为reverseValue。
- toggle:状态在defaultValue和reverseValue中切换。
- set:带参数,切换为defaultValue或者reverseValue。
使用示例
export default () => {
const [state, { toggle, set, setLeft, setRight }] = useToggle('yes', 'no');
return (
<div>
<p>{state}</p>
<p>
<button type="button" onClick={toggle}>
Toggle
</button>
<button type="button" onClick={() => set('yes')} style={{ margin: '0 8px' }}>
Set yes
</button>
<button type="button" onClick={() => set('no')}>
Set no
</button>
<button type="button" onClick={setLeft} style={{ margin: '0 8px' }}>
Set Left
</button>
<button type="button" onClick={setRight}>
Set Right
</button>
</p>
</div>
);
};
源码分析
import { useMemo, useState } from 'react';
//定义了动作接口,内含四个方法
export interface Actions<T> {
setLeft: () => void;
setRight: () => void;
set: (value: T) => void;
toggle: () => void;
}
//进行三次函数重载
function useToggle<T = boolean>(): [boolean, Actions<T>];
function useToggle<T>(defaultValue: T): [T, Actions<T>];
function useToggle<T, U>(defaultValue: T, reverseValue: U): [T | U, Actions<T | U>];
function useToggle<D, R>(defaultValue: D = false as unknown as D, reverseValue?: R) {
//内部使用useState创建了基本的state,类型为联合类型D | R,
//也就是传入的两种状态:defaultValue和reverseValue(如果有)的类型
const [state, setState] = useState<D | R>(defaultValue);
//用useMemo包装,返回四个方法
const actions = useMemo(() => {
//定义reverseValueOrigin,为reverseValue或!defaultValue(根据reverseValue是否存在)
const reverseValueOrigin = (reverseValue === undefined ? !defaultValue : reverseValue) as D | R;
const toggle = () => setState((s) => (s === defaultValue ? reverseValueOrigin : defaultValue));
const set = (value: D | R) => setState(value);
const setLeft = () => setState(defaultValue);
const setRight = () => setState(reverseValueOrigin);
return {
toggle,
set,
setLeft,
setRight,
};
// useToggle ignore value change
// }, [defaultValue, reverseValue]);
}, []);
return [state, actions];
}
export default useToggle;
源码的内部逻辑较为简单:
- 首先定义了动作接口,包含该hook的四个改变状态的方法。
- 内部使用了useState创建了基本的state,类型为联合类型(即传入的两个初始值的类型)。
- 使用useMemo定义四个改变状态的方法并return。
- 值得注意的是在封装方法的时候使用了useMemo。
要点说明:useMemo的使用
useMemo的作用跟useCallback相似,只是用法有所不同。useMemo的计算结果是回调函数中return的值,在useToggle源码中为四个方法
该hook返回一个memoized值,仅在第二项参数数组中的某一依赖项发生改变时才会重新计算;而在上述使用场景中,依赖项为空数组,那么就在初始的时候只执行一次,当组件重新渲染时不会再执行,有助于减少消耗。
参考资料:
https://react.docschina.org/d...
useBoolean
该hook用于管理 boolean 状态。可以看出useBoolean与useToggle很相似,只是适用范围更加狭窄;实际上useBoolean确实是使用useToggle封装,这也是本文将二者放在一起讨论的原因。
基本用法
四个方法
- setTrue:state修改为true。
- setFalse:state修改为false。
- toggle:状态在true和false中切换。
- set:带参数,将状态设置为true或false。
使用示例
const [state, { toggle, setTrue, setFalse }] = useBoolean(true);
源码分析
该源码较为简单,内部直接使用了useToggle进行封装。
import { useMemo } from 'react';
import useToggle from '../useToggle';
//规定了Actions接口,包含四个方法
export interface Actions {
setTrue: () => void;
setFalse: () => void;
set: (value: boolean) => void;
toggle: () => void;
}
export default function useBoolean(defaultValue = false): [boolean, Actions] {
//使用useToggle进行封装,并直接用了它的toggle, set方法
const [state, { toggle, set }] = useToggle(defaultValue);
//用useMemo包装,返回四个方法
const actions: Actions = useMemo(() => {
const setTrue = () => set(true);
const setFalse = () => set(false);
return {
toggle,
set: (v) => set(!!v),
setTrue,
setFalse,
};
}, []);
return [state, actions];
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。