当前位置:首页 » 《关于电脑》 » 正文

【实战】用 Custom Hook + TS泛型实现 useArray

28 人参与  2024年04月02日 19:15  分类 : 《关于电脑》  评论

点击全文阅读


文章目录

一、题目二、答案(非标准)三、关键知识点1.Custom Hook关键点案例useMountuseDebounce 2.TS 泛型关键点


一、题目

完善自定义 Hook —— useArray ,使其能够完成 tryUseArray 组件中测试的功能:

入参:数组返回值: value:最新状态的数组;add:添加元素;removeIndex:移除数组特定位置的元素;clear:清空数组;

相关文件代码:

src\utils\index.ts
import { useEffect, useState } from "react";export const useMount = (cbk: () => void) => useEffect(() => cbk(), []);export const useArray = () => {};
src\tryUseArray.tsx
import { useArray, useMount } from "utils";const TryUseArray = () => {  const persons: { name: string; age: number }[] = [    { name: "jack", age: 25 },    { name: "ma", age: 22 },  ];  const { value, clear, removeIndex, add } = useArray(persons);  useMount(() => {    // 期待这里报错:Property 'notExist' does not exist on type '{ name: string; age: number; }[]'.    // console.log(value.notExist);    // 期待这里报错:Property 'age' is missing in type '{ name: string; }' but required in type '{ name: string; age: number; }'.    // add({ name: "david" });    // 期待这里报错:Argument of type 'string' is not assignable to parameter of type 'number'.    // removeIndex("123");  });  return (    <div>      {/*期待: 点击以后增加 john */}      <button onClick={() => add({ name: "john", age: 22 })}>add john</button>      {/*期待: 点击以后删除第一项*/}      <button onClick={() => removeIndex(0)}>remove 0</button>      {/*期待:点击以后清空列表*/}      <button style={{ marginBottom: "50px" }} onClick={() => clear()}>        clear      </button>      {value.map((person, index) => (        <div key={index} style={{ marginBottom: "30px" }}>          <span style={{ color: "red" }}>{index}</span>          <span>{person.name}</span>          <span>{person.age}</span>        </div>      ))}    </div>  );};export default TryUseArray;
src\App.tsx
import "./App.css";import TryUseArray from "tryUseArray";function App() {  return (    <div className="App">      <TryUseArray />    </div>  );}export default App;

答 答 答
案 案 案
在 在 在
后 后 后
面 面 面
, , ,
没 没 没
有 有 有
完 完 完
成 成 成
不 不 不
要 要 要
偷 偷 偷
看 看 看
哦 哦 哦
! ! !

二、答案(非标准)

import { useEffect, useState } from "react";// 我的练习作业// export const useArray = <T>(array: T[]) => {//   const [value, setValue] = useState(array)//   const clear = () => setValue([])//   const removeIndex = (index: number) => setValue([...value].filter((item, _index) => _index !== index))//   const add = (item: item) => setValue([...value, item]))//   return {//     value, clear, removeIndex, add//   }// }export const useArray = <T>(array: T[]) => {  const [value, setValue] = useState(array);  return {    value,    add: (item: T) => setValue([...value, item]),    removeIndex: (index: number) => {      const temp = [...value];      temp.splice(index, 1);      setValue(temp);    },    clear: () => setValue([]),  };};

三、关键知识点

1.Custom Hook

官方文档:自定义 Hook – React

关键点

定义 Custom Hook 是一个函数,名字必须以 use 开头hook 只能在 React 函数组件 或其他 Hook 函数中调用(普通 js/ts 函数中不可用)相同的 Hook 不共享 state (重用状态逻辑的机制,所有 state 和副作用都是完全隔离的)不要在循环,条件或嵌套函数中调用 Hook(建议在 Hook 内部使用循环,条件或嵌套函数)React 16.8+ 中使用 Hook 规则 – React

案例

useMount
封装
export const useMount = (cbk: () => void) => useEffect(() => cbk(), []);
调用
import { useMount } from "utils";const [list, setList] = useState([]);useMount(() => {  fetch(`${apiUrl}/list`).then(async (res) => {    if (res.ok) {      setList(await res.json());    }  });});
useDebounce
封装
/** * @param { 值 } val * @param { 延时:默认 1000 } delay * @returns 在某段时间内多次变动后最终拿到的值(delay 延迟的是存储在队列中的上一次变化) */export const useDebounce = <V>(val: V, delay: number = 1000) => {  const [tempVal, setTempVal] = useState(val);  useEffect(() => {    // 每次在 val 变化后,设置一个定时器    const timeout = setTimeout(() => setTempVal(val), delay);    // 每次在上一个 useEffect 处理完以后再运行(useEffect 的天然功能即是在运行结束的 return 函数中清除上一个(同一) useEffect)    return () => clearTimeout(timeout);  }, [val, delay]);  return tempVal;};
调用
import { useDebounce } from "utils";// 对 param 进行防抖处理const lastParam = useDebounce(param);const [list, setList] = useState([]);useEffect(() => {  fetch(    // name=${param.name}&personId=${param.personId}    `${apiUrl}/projects?${qs.stringify(lastParam)}`  ).then(async (res) => {    if (res.ok) {      setList(await res.json());    }  });}, [lastParam]);

注意区别于 节流

拓展学习:

【笔记】Custom Hook

2.TS 泛型

官方文档:

TypeScript: Documentation - Generics泛型(generic) - TypeScript 中文手册

关键点

不预先指定其具体的类型,而在使用的时候再进行定义函数是对“值”的编程,泛型是对“类型”的编程泛型是类型的变量

拓展学习:

【笔记】TS 泛型

点击全文阅读


本文链接:http://m.zhangshiyu.com/post/89743.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 千金难泣(立轩苏子骞翠竹吴进)全本免费在线阅读_千金难泣最新章节在线阅读(立轩苏子骞翠竹吴进)
  • 《沈云阶傅宴辞》(沈云阶傅宴辞》已完结完整版全集大结局小说)全文阅读笔趣阁
  • 《沈凌峰沈国华》已完结小说全文阅读笔趣阁《沈凌峰沈国华》
  • 《傅嫤韩恬魏郯程茂》已完结(傅嫤韩恬魏郯程茂)热门小说全目录完整版)全文阅读笔趣阁
  • 八零俏军医错嫁糙汉军官:番外+全文+后续(贺昭朗孟翩然)完本小说免费_全本免费小说八零俏军医错嫁糙汉军官:番外+全文+后续最新小说全文阅读(贺昭朗孟翩然)
  • 失去千千万万遍在线阅读(阮相宜陆凛言)全文免费阅读无弹窗大结局_(失去千千万万遍在线阅读)失去千千万万遍在线阅读免费阅读全文最新章节列表_笔趣阁(失去千千万万遍在线阅读) -
  • 脱离世界后,妻子疯了火爆小说小说(沈夕颜林程言)全文免费阅读无弹窗大结局_(脱离世界后,妻子疯了火爆小说免费阅读全文大结局)最新章节列表_笔趣阁(脱离世界后,妻子疯了火爆小说) -
  • 跨年发生踩踏,男友为救白月光丢下我(温林初宝宝)免费阅读 -
  • 都重生了,还不离婚等啥呢宋招弟霍文铮小说在线章节免费阅读
  • 已完结小说《这皇后谁爱当谁当,狗皇帝我不要了》免费阅读
  • 哥哥们为讨好假千金,把我困死在酒桶最新章节,哥哥们为讨好假千金,把我困死在酒桶免费阅读
  • 开局成胎,赠娘亲吞天魔功小说免费资源,开局成胎,赠娘亲吞天魔功在线阅读

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1