自定义hook复用组件代码

2022-07-03  本文已影响0人  马建阳
  1. 概念: 自定义hook是react中最新的组件代码复用方案
    注意点: hook必须以use开头,并需要使用别的hook
  2. 例子
    1)useEffect
useEffect(() => {
    fetch(`${apiUrl}/users`).then(async response => {
      if (response.ok) {
        setUsers(await response.json())
      }
    })
  }, [])

改造后

export const useMount = (callback) => {
  useEffect(() => {
    callback();
  }, []);

useMount(() => {
    fetch(`${apiUrl}/users`).then(async response => {
      if (response.ok) {
        setUsers(await response.json())
      }
    })
  })
  1. useDebounce

常用debounce

const debounce = (func, delay) => {
  let timeout;
  return (...param) => {
    if (timeout) {
      clearTimeout(timeout);
    }
    timeout = setTimeout(function() {
      func(...param);
    }, delay);
  }
}

const log = debounce(() => console.log('call'), 5000)
log()
log()
log()

但在以下场景使用并不优雅

const [param, setParam] = useState({
    name: '',
    personId: ''
  })

useEffect(() => {
    fetch(`${apiUrl}/projects?${qs.stringify(cleanObject(param))}`).then(async response => {
      if (response.ok) {
        setList(await response.json())
      }
    })
  }, [param])

通过useDebounce来

export const useDebounce = (value, delay) => {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    // 每次在value变化以后,设置一个定时器
    const timeout = setTimeout(() => setDebouncedValue(value), delay);
    // 每次在上一个useEffect处理完以后再运行
    return () => clearTimeout(timeout);
  }, [value, delay]);

  return debouncedValue;
};

const [param, setParam] = useState({
    name: '',
    personId: ''
  })
const debouncedParam = useDebounce(param, 2000)

useEffect(() => {
    fetch(`${apiUrl}/projects?${qs.stringify(cleanObject(debouncedParam))}`).then(async response => {
      if (response.ok) {
        setList(await response.json())
      }
    })
  }, [debouncedParam])

  1. useArray
import { useArray, useMount } from "utils";
import React, { useState } from "react";

export const TsReactTest = () => {
  const persons: { name: string; age: number }[] = [
    { name: "jack", age: 25 },
    { name: "ma", age: 22 },
  ];
  const { value, clear, removeIndex, add } = useArray(persons);

  return (
    <div>
    {value.map((person, index) => (
        <div style={{ marginBottom: "30px" }}>
          <span style={{ color: "red" }}>{index}</span>
          <span>{person.name}</span>
          <span>{person.age}</span>
        </div>
      ))}
      {/* 点击以后清空列表*/}
      <button style={{ marginBottom: "50px" }} onClick={() => clear()}>
        clear
      </button>
      {/* 点击以后删除第一项*/}
      <button onClick={() => removeIndex(0)}>remove 0</button>
      {/* 点击以后增加 john */}
      <button onClick={() => add({ name: "john", age: 22 })}>add john</button>
    </div>
  );


export const useArray = <T>(initialArray: T[]) => {
  const [value, setValue] = useState(initialArray);
  return {
    value,
    setValue,
    add: (item: T) => setValue([...value, item]),
    clear: () => setValue([]),
    removeIndex: (index: number) => {
      const copy = [...value];
      copy.splice(index, 1);
      setValue(copy);
    },
  };
};

上一篇 下一篇

猜你喜欢

热点阅读