这样定义状态,你是否更加喜欢?

1,211 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

学习ahooks需要你抱着这样的态度去学习:你可以不会,但你不能不知道,万一哪天用到了呢

本文将介绍 useBoolean、useToggle、useSet、useSetState、useCounter、useReactive,六个Api

跟之前一样我们通过 ⭐️ 做个标记,说明钩子的重要性

⭐️:一般; ⭐️⭐️:重要; ⭐️⭐️⭐️:很重要

在所介绍的这些钩子中,尤其注意 useReactive 这个钩子,相信他能给予你很多帮助(● ̄(エ) ̄●)

演示示例: Domesy/ahook

useBoolean 布尔值

推荐指数:⭐️

参数意义:

  • toggle:触发可改变其状态值
  • setTrue:将状态设置为true
  • setFalse:将状态设置为false

代码示例

import React from 'react';
  import { Button } from 'antd';
  import { useBoolean } from 'ahooks';

  const Mock: React.FC<any> = () => {
    const [state, { toggle, setTrue, setFalse }] = useBoolean(true);

    return (
      <>
        <p>状态值:{JSON.stringify(state)}</p>
        <div style={{display: 'flex', justifyContent: 'flex-start'}}>
          <Button type='primary' onClick={() => toggle()}>
            切换
          </Button>
          <Button type='primary' onClick={() => setFalse()} style={{margin:'0 30px'}}>
            设置false
          </Button>
          <Button type='primary' onClick={() => setTrue()}>
            设置true
          </Button>
        </div>
      </>
    );
  };

  export default Mock;

useToggle 两种状态之间的切换

推荐指数:⭐️

useToggle:普通用法与 useBoolean 的用法一致,高级用法,可支持两种状态之间的切换

参数意义:

  • toggle: 切换状态
  • set: 修改状态
  • setLeft:设置为第一个值
  • setRight: 设置为第二个值,如果没有则为第一个值

代码示例

  import React from 'react';
  import { Button } from 'antd';
  import { useToggle } from 'ahooks';

  const Mock: React.FC<any> = () => {
    const [state, { toggle, set, setLeft, setRight }] = useToggle('Hello', 'World');
    const [boolean , { toggle:toggleBool, set: toggleSet }] = useToggle(false);

    return (
      <>
        <div style={{fontWeight: 'bolder'}}>基础用法(与useBoolean使用一直):</div>
        <div style={{marginTop: 8, fontWeight: 'bolder'}}>状态:{JSON.stringify(boolean)}</div>
        <div style={{justifyContent: 'flex-start', display:'flex', marginTop: 8}}>
          <Button type='primary' style={{marginRight: 8}} onClick={() =>  toggleBool()}>切换</Button>
          <Button type='primary' style={{marginRight: 8}} onClick={() =>  toggleSet(false)}>切换1</Button>
          <Button type='primary' style={{marginRight: 8}} onClick={() =>  toggleSet(true)}>切换2</Button>

        </div>
        <div style={{marginTop: 8, fontWeight: 'bolder'}}>高级用法:</div>
        <div style={{marginTop: 8}}>两种状态切换:{state}</div>
        <div style={{justifyContent: 'flex-start', display:'flex', marginTop: 8}}>
          <Button type='primary' style={{marginRight: 8}} onClick={() =>  toggle()}>切换</Button>
          <Button type='primary' style={{marginRight: 8}} onClick={() => set('Hello1')} >切换为 hello</Button>
          <Button type='primary' style={{marginRight: 8}} onClick={() => set('World')} >切换为 World</Button>
        </div>
        <div style={{justifyContent: 'flex-start', display:'flex', marginTop: 8}}>
          <Button type='primary' style={{marginRight: 8}} onClick={() => setLeft()} >设置为Hello</Button>
          <Button type='primary' style={{marginRight: 8}} onClick={() => setRight()} >设置为World</Button>
        </div>
      </>
    );
  };

  export default Mock;

useSet 管理Set类型

推荐指数:⭐️⭐️

useSet: 包含 set(Set对象),有功能:添加元素(add)移除元素(remove)判断元素是否存在(hsa)重置(reset)功能

代码示例

 import React from 'react';
  import { Button } from 'antd';
  import { useSet, useCounter } from 'ahooks';

  const Mock: React.FC<any> = () => {
    const [set, { add, has, remove, reset }] = useSet(['Hello']);
    const [current, { inc, reset:countReset }] = useCounter(1);

    return (
      <>
        <div style={{justifyContent: 'flex-start', display:'flex',}}>
          <Button type='primary' style={{marginRight: 8}} onClick={() => {
            inc()
            add(String(Method.getDate({add: current})))
          }}>
            日期加1
          </Button>
          <Button type='primary' style={{marginRight: 8}} onClick={() => remove('Hello')} disabled={!has('Hello')} >删除 Hello</Button>
          <Button type='primary' style={{marginRight: 8}} onClick={() => {reset(); countReset()}} >重置</Button>
        </div>

        <div style={{ marginTop: 16 }}>
          <pre>{JSON.stringify(Array.from(set), null, 2)}</pre>
        </div>
      </>
    );
  }

  export default Mock;

useSetState 管理Object类型

推荐指数:⭐️⭐️

useSetState: 简而言之,就是类组件的 this.setState, 他可以接收任意组件的类型

代码示例

import React from 'react';
  import { Button } from 'antd';
  import { useSetState } from 'ahooks';

  interface State {
    hello: string;
    count: number;
    [key: string]: any;
  }


  const Mock: React.FC<any> = () => {
    const [state, setState] = useSetState<State>({
      hello: '',
      count: 0,
    });

    return (
      <>
        <div style={{justifyContent: 'flex-start', display:'flex',}}>
          <Button type='primary' style={{marginRight: 8}} onClick={() => setState({ hello: 'domesy' })}>
            设置 hello
          </Button>
          <Button type='primary' style={{marginRight: 8}} onClick={() => setState({ domesy: '欢迎👏🏻' })} >设置任意值,domesy</Button>
          <Button type='primary' style={{marginRight: 8}} onClick={() => setState((prev) => ({ count: prev.count + 1 }))} >加1</Button>
        </div>
        <pre>{JSON.stringify(state, null, 2)}</pre>
      </>
    );
  };

  export default Mock;

useCounter 数字管理器

推荐指数:⭐️⭐️

可以设置数字的范围,如:最大值、最小值,并有操作 增加,减少,设置,重置四个功能

无论是初始值还是,增加,减少,所设定的值在 最大、最小值之间,如过高于最大值,则 current 为最大值,反之亦然

import React from 'react';
  import { Button } from 'antd';
  import { useCounter } from 'ahooks';

  const Mock: React.FC<any> = () => {
    const [current, { inc, dec, set, reset }] = useCounter(100, { min: 1, max: 10 });

    return (
      <>
        <div>数字:{ current } 范围(最小:1,最大为:10)</div>
        <div style={{display: 'flex',justifyContent: 'flex-start', marginTop: 8}}>
          <Button type="primary" style={{marginRight: 8}} onClick={() => inc()}>加1</Button>
          <Button type="primary" style={{marginRight: 8}} onClick={() => inc(2)}>加2</Button>
          <Button type="primary" style={{marginRight: 8}} onClick={() => dec()}>减一</Button>
          <Button type="primary" style={{marginRight: 8}} onClick={() => set(3)}>设置为3</Button>
          <Button type="primary" onClick={() => reset()}>重置</Button>
        </div>
      </>
    );
    };

  export default Mock;

useReactive 另一种useState

推荐指数: ⭐️⭐️⭐️

useReactive:一种数据响应式的操作体验,定义数据状态不需要写useState , 直接修改属性即可刷新视图。 可进行任意属性的复制,包括操作属性,类似于全局变量,可以直接改变

简单说就是任意类型都可设置,非常方便

image.png

代码示例

 import React, { useState } from 'react';
 import { Button } from 'antd';
 import { useReactive } from 'ahooks';
 
 const Mock: React.FC<any> = () => {

   const state = useReactive<any>({
     count: 0,
     inputVal: 'hello',
     bool: false,
     arr: [],
     bug: '',
     bugs: ['domesy', 'react', 'hook'],
     addBug(bug:string) {
       this.bugs.push(bug);
     },
     get bugsCount() {
       return this.bugs.length;
     },
   });
   
   return (
     <>
       <div style={{fontWeight: 'bold'}}>基本使用:</div>
       <div style={{marginTop: 8}}> 对数字进行操作:{state.count}</div>
       <div style={{margin: '8px 0', display: 'flex',justifyContent: 'flex-start'}}>
         <Button type="primary" onClick={() => state.count++ } >加1</Button>
         <Button type="primary" style={{marginLeft: 8}} onClick={() => state.count-- } >减1</Button>
         <Button type="primary" style={{marginLeft: 8}} onClick={() => state.count = 5 } >设置为5</Button>
       </div>
       <div style={{marginTop: 8}}> 对Boolean进行操作:{state.bool ? 'true' : 'false'}</div>
       <div style={{margin: '8px 0', display: 'flex',justifyContent: 'flex-start'}}>
         <Button type="primary" onClick={() => state.bool = !state.bool } >切换状态</Button>
       </div>
       <div style={{marginTop: 8}}> 对字符串进行操作:{state.inputVal}</div>
       <div style={{margin: '8px 0', display: 'flex',justifyContent: 'flex-start'}}>
         <Button type="primary" onClick={() => state.inputVal = 'hello' } >设置为 hello</Button>
         <Button type="primary" style={{marginLeft: 8}} onClick={() => state.inputVal = 'word' } >设置为 word</Button>
         <Button type="primary" style={{marginLeft: 8}}
         onClick={() => {
           if(state.inputVal === 'word'){
             state.inputVal = 'hello'
           }else{
             state.inputVal = 'word'
           }
         }} >切换</Button>
       </div>
       <div style={{marginTop: 8}}> 对数组进行操作:{JSON.stringify(state.arr)}</div>
       <div style={{margin: '8px 0', display: 'flex',justifyContent: 'flex-start'}}>
         <Button type="primary" onClick={() => state.arr.push(Math.floor(Math.random() * 100))} >push</Button>
         <Button type="primary" style={{marginLeft: 8}} onClick={() => state.arr.pop()} >pop</Button>
         <Button type="primary" style={{marginLeft: 8}} onClick={() => state.arr.shift()} >shift</Button>
         <Button type="primary" style={{marginLeft: 8}} onClick={() => state.arr.unshift(Math.floor(Math.random() * 100))} >unshift</Button>
         <Button type="primary" style={{marginLeft: 8}} onClick={() => state.arr.reverse()} >reverse</Button>
         <Button type="primary" style={{marginLeft: 8}} onClick={() => state.arr.sort()} >sort</Button>
       </div>
       <div style={{fontWeight: 'bold', marginTop: 8}}>计算属性:</div>
       <div style={{marginTop: 8}}>数量:{ state.bugsCount } 个</div>
       <div style={{margin: '8px 0'}}>
         <form
           onSubmit={(e) => {
             state.bug ? state.addBug(state.bug) : state.addBug('domesy')
             state.bug = '';
             e.preventDefault();
           }}
         >
           <input type="text" value={state.bug} onChange={(e) => (state.bug = e.target.value)} />
           <button type="submit"  style={{marginLeft: 8}} >增加</button>
           <Button type="primary" style={{marginLeft: 8}} onClick={() => state.bugs.pop()}>删除</Button>
         </form>

       </div>
       <ul>
         {
           state.bugs.map((bug:any, index:number) => (
             <li key={index}>{bug}</li>
           ))
         }
       </ul>
     </>
   );
 };

 export default Mock;

End

希望跟我一样的小菜鸟亲自动手试试,加深记忆,了解就好~

其他文章