React Hook学习

91 阅读1分钟

1. 实现目的

  1. 将组件逻辑提取到可重用的函数中
  2. 实现同一套数据源管控不同的组件(子组件)

2. 自定义Hook的规范

  1. 自定义Hook是一个函数, 名称以 use开头,采用小驼峰方式命名 useTag
  2. Hook内部可以调用其他的Hook
  3. 一个组件只能在最顶层使用Hook, 不要在循环,条件或嵌套函数中调用 Hook。 确保总是在你的 React 函数的最顶层以及任何 return 之前调用Hook
  4. 只能在React函数组件调用Hook

3. 自定义组件开发示例

3.1 最基本的钩子

import React, { useState } from 'react';
// 加减简单计数器
function useCounter(initialValue) {
  // 接受初始化的值生成state
  const [count, changeCount] = useState(initialValue);
  // 声明减少的方法
  const decrease = () => {
    changeCount(count - 1);
  }
  // 声明增加的方法
  const increase = () => {
    changeCount(count + 1);
  }
  // 声明重置计数器方法
  const resetCounter = () => {
    changeCount(0);
  }
  // 将count数字与方法返回回去
  return [count, { decrease, increase, resetCounter }]
}

export default function myHooksView() {
  // 在函数组件中使用我们自己编写的hook生成一个计数器,并拿到所有操作方法的对象
  const [count, controlCount] = useCounter(10);
  return (
      <div>
        当前数量:{count}
            <button onClick={controlCount.decrease}>减少</button>
            <button onClick={controlCount.increase}>增加</button>
            <button onClick={controlCount.resetCounter}>重置</button>
    </div>
  )
}

3.2 返回DOM与其他方法的钩子

import React, { ReactNode, useEffect, useState } from 'react';

function useModal(id: string | null) {
  const [visible, changeVisible] = useState(false);
  const [list, setList] = useState<number[]>([]);

  useEffect(() => {
    getData()
  }, [id])
  
  const toggleModalVisible:() => void = () => {
    changeVisible(!visible);
  };

  const getData:() => void = () => {
    setTimeout(() => {
      setList([0, 9, 8])
    }, 9)
  }

  const getEle:() => ReactNode = () => {
    return <div>
      这是子组件内容
    </div>
  }

  const getEle1:() => ReactNode = () => {
    return <div>
      这是子组件3333内容
    </div>
  }

  const getAsyncEle:() => ReactNode = () => {
    return <div>
      {
        list.map((item) => {
          return <div>{ item }</div>
        })
      }
    </div>
  }

  const getAsyncFEle:() => ReactNode = () => {
    console.log(id, 'sera')
    return <div>
      {
        list.map((item) => {
          return <div>{ item }</div>
        })
      }
    </div>
  }

  return [getEle(), getEle1(), getAsyncEle(), getAsyncFEle(), {
    toggleModalVisible,
  }];
}

export default function HookDemo() {
  const [id, setId] = useState<string | null>(null);
  const [getEle, getEle1, getAsyncEle] = useModal(id);

  useEffect(() => {
    getData()
  }, [])

  const getData: () => void = () => {
    setTimeout(() => {
      setId('000')
    }, 1000)
  }

  return (
    <div>
      {getEle}
      {getEle1}
      {getAsyncEle}
    </div>
  );
}