当前位置: 首页 > news >正文

长沙一站式网站建设曲靖新闻今日头条

长沙一站式网站建设,曲靖新闻今日头条,佛山专业网站制作公司,商城网站建设服务器文章目录 一、项目起航:项目初始化与配置二、React 与 Hook 应用:实现项目列表三、TS 应用:JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook&…

文章目录

    • 一、项目起航:项目初始化与配置
    • 二、React 与 Hook 应用:实现项目列表
    • 三、TS 应用:JS神助攻 - 强类型
    • 四、JWT、用户认证与异步请求
    • 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式
    • 六、用户体验优化 - 加载中和错误状态处理
    • 七、Hook,路由,与 URL 状态管理
      • 1+2.
      • 3~6
      • 7.完成URL状态管理与JS中的 iterator讲解


学习内容来源:React + React Hook + TS 最佳实践-慕课网


相对原教程,我在学习开始时(2023.03)采用的是当前最新版本:

版本
react & react-dom^18.2.0
react-router & react-router-dom^6.11.2
antd^4.24.8
@commitlint/cli & @commitlint/config-conventional^17.4.4
eslint-config-prettier^8.6.0
husky^8.0.3
lint-staged^13.1.2
prettier2.8.4
json-server0.17.2
craco-less^2.0.0
@craco/craco^7.1.0
qs^6.11.0
dayjs^1.11.7
react-helmet^6.1.0
@types/react-helmet^6.1.6
react-query^6.1.0
@welldone-software/why-did-you-render^7.0.1
@emotion/react & @emotion/styled^11.10.6

具体配置、操作和内容会有差异,“坑”也会有所不同。。。


一、项目起航:项目初始化与配置

  • 一、项目起航:项目初始化与配置

二、React 与 Hook 应用:实现项目列表

  • 二、React 与 Hook 应用:实现项目列表

三、TS 应用:JS神助攻 - 强类型

  • 三、 TS 应用:JS神助攻 - 强类型

四、JWT、用户认证与异步请求

  • 四、 JWT、用户认证与异步请求(上)

  • 四、 JWT、用户认证与异步请求(下)

五、CSS 其实很简单 - 用 CSS-in-JS 添加样式

  • 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式(上)

  • 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式(下)

六、用户体验优化 - 加载中和错误状态处理

  • 六、用户体验优化 - 加载中和错误状态处理(上)

  • 六、用户体验优化 - 加载中和错误状态处理(中)

  • 六、用户体验优化 - 加载中和错误状态处理(下)

七、Hook,路由,与 URL 状态管理

1+2.

  • 七、Hook,路由,与 URL 状态管理(上)

3~6

  • 七、Hook,路由,与 URL 状态管理(中)

7.完成URL状态管理与JS中的 iterator讲解

searchParams 拿到了, 接下来用暴露出来的 setSearchParams 来替换 ProjectList 里的 setParam

修改 src\screens\ProjectList\index.tsx

...
export const ProjectList = () => {const [param, setParam] = useUrlQueryParam(["name", "personId"]);...
};
...

但是这样使用 setParam 时若是传入一个 { name1: 'Jack' } 的参数,没有任何报错拦截,这样肯定是不行的,所以需要在 setParamsetSearchParams 中使用对 key 的判断

修改 src\utils\url.ts

import { useMemo } from "react";
import { URLSearchParamsInit, useSearchParams } from "react-router-dom";
import { cleanObject } from "utils";
...
export const useUrlQueryParam = <K extends string>(keys: K[]) => {const [searchParams, setSearchParams] = useSearchParams();return [useMemo(() => keys.reduce((prev, key) => {// searchParams.get 可能会返回 null,需要预设值来兼容return { ...prev, [key]: searchParams.get(key) || "" };// 初始值会对类型造成影响,需要手动指定}, {} as { [key in K]: string }),// eslint-disable-next-line react-hooks/exhaustive-deps[searchParams]),(params: Partial<{ [key in K]: unknown }>) => {const o = cleanObject({ ...Object.fromEntries(searchParams), ...params }) as URLSearchParamsInitreturn setSearchParams(o)},] as const;
};
  • 遇到类似下面这样的类型不匹配问题,可以直接使用 as 来强制指定为提示的类型
    • 类型“{ [x: string]: unknown; }”的参数不能赋给类型“URLSearchParamsInit | ((prev: URLSearchParams) => URLSearchParamsInit) | undefined”的参数。

通过 Object.fromEntries 引出 Iterator 的概念:

Symbol.iterator 为每一个对象定义了默认的迭代器。该迭代器可以被 for...of 循环使用。

Symbol.iterator - JavaScript | MDN

在浏览器的 console 中做个小实验:

  • 定义一个数组并使用 for..of 遍历
let arr = [1, 2, 3]
for(v of arr) { console.log(v) }
// 1
// 2
// 3
  • 通过 Symbol.iterator 属性查看 此数组的 遍历器
arr[Symbol.iterator]
// ƒ values() { [native code] }
  • 将其执行结果拿出来
let i = a[Symbol.iterator]()
i
// Array Iterator {}
//  [[Prototype]]: Array Iterator
//    next: ƒ next()
//    Symbol(Symbol.toStringTag): "Array Iterator"
//    [[Prototype]]: Object
  • 可以看到它有个 next() 方法,执行一下
i.next()
// {value: 1, done: false}
i.next()
// {value: 2, done: false}
i.next()
// {value: 3, done: false}
i.next()
// {value: undefined, done: true}
  • 接下来实现一下自定义遍历器
const obj = {data: ["hello", "world"],[Symbol.iterator]() {const self = this;let index = 0;return {next() {if (index < self.data.length) {return {value: self.data[index++] + "!",done: false};} else {return { value: undefined, done: true };}}};}
};for (let o of obj) {console.log(o);
}

线上地址:https://codesandbox.io/s/upbeat-wood-bum3j

回归项目代码,searchParamsURLSearchParams 类型,通过以下代码可以看出使用 Object.fromEntries 可以将其(entries)转为 object

new URLSearchParams({name: 'Jack'})[Symbol.iterator]
// ƒ entries() { [native code] }

代码逻辑明白了,接下来看下页面效果:

  • http://localhost:3000/projects?name=骑手&personId=18 直接访问,参数在页面中保持
  • 在页面中修改参数,URL 中同时更改,但有个小问题,下拉选择负责人时,页面中展示的是 personId,接下来解决一下

src\screens\ProjectList\index.tsx 中打印 param

src\screens\ProjectList\components\SearchPanel.tsx 中打印 users

运行代码可以发现,paramidstringusers 中是 number,没有很好兼容,暂时在src\screens\ProjectList\components\SearchPanel.tsx 中将 id 强制转换为 stringString(user.id)):

...
export const SearchPanel = ({ users, param, setParam }: SearchPanelProps) => {return (<Form css={{ marginBottom: "2rem", ">*": "" }} layout="inline">...<Form.Item><Select {...}><Select.Option value="">负责人</Select.Option>{users.map((user) => (<Select.Option key={user.id} value={String(user.id)}>...</Select.Option>))}</Select></Form.Item></Form>);
};

查看页面效果,功能正常啦!


部分引用笔记还在草稿阶段,敬请期待。。。


文章转载自:
http://userinfo.c7507.cn
http://ecchymosis.c7507.cn
http://scrambler.c7507.cn
http://lilied.c7507.cn
http://resin.c7507.cn
http://afterdamp.c7507.cn
http://nonaligned.c7507.cn
http://bedivere.c7507.cn
http://approvingly.c7507.cn
http://theatre.c7507.cn
http://interarticular.c7507.cn
http://shri.c7507.cn
http://vandalism.c7507.cn
http://sailcloth.c7507.cn
http://dejectile.c7507.cn
http://kuznetsk.c7507.cn
http://outproduce.c7507.cn
http://siogon.c7507.cn
http://teenage.c7507.cn
http://utilidor.c7507.cn
http://flyable.c7507.cn
http://seto.c7507.cn
http://epicycle.c7507.cn
http://regalist.c7507.cn
http://tattie.c7507.cn
http://quadriga.c7507.cn
http://kazatsky.c7507.cn
http://glandiferous.c7507.cn
http://condyle.c7507.cn
http://thaumaturgist.c7507.cn
http://squabbish.c7507.cn
http://clicket.c7507.cn
http://infinitude.c7507.cn
http://hydroxonium.c7507.cn
http://loid.c7507.cn
http://polarizability.c7507.cn
http://maulvi.c7507.cn
http://uncreative.c7507.cn
http://gastroduodenostomy.c7507.cn
http://lettered.c7507.cn
http://rodential.c7507.cn
http://anticapitalist.c7507.cn
http://allision.c7507.cn
http://epiclesis.c7507.cn
http://fallow.c7507.cn
http://packboard.c7507.cn
http://juba.c7507.cn
http://photoscanner.c7507.cn
http://advent.c7507.cn
http://multiphase.c7507.cn
http://platoon.c7507.cn
http://geoelectric.c7507.cn
http://pedodontic.c7507.cn
http://supermart.c7507.cn
http://angelhood.c7507.cn
http://imperiously.c7507.cn
http://vilma.c7507.cn
http://macrospore.c7507.cn
http://metalline.c7507.cn
http://whangdoodle.c7507.cn
http://uropygium.c7507.cn
http://noiseproof.c7507.cn
http://pachouli.c7507.cn
http://culprit.c7507.cn
http://rachides.c7507.cn
http://draftee.c7507.cn
http://covenantor.c7507.cn
http://concupiscence.c7507.cn
http://lucille.c7507.cn
http://discern.c7507.cn
http://demitint.c7507.cn
http://orthogonalize.c7507.cn
http://multiresistant.c7507.cn
http://indign.c7507.cn
http://carmarthenshire.c7507.cn
http://coppery.c7507.cn
http://slew.c7507.cn
http://blackly.c7507.cn
http://debris.c7507.cn
http://waveless.c7507.cn
http://snell.c7507.cn
http://graftabl.c7507.cn
http://spacial.c7507.cn
http://crip.c7507.cn
http://stumpy.c7507.cn
http://hypogamy.c7507.cn
http://agnolotti.c7507.cn
http://canephora.c7507.cn
http://caudad.c7507.cn
http://unactuated.c7507.cn
http://soundscriber.c7507.cn
http://reprimand.c7507.cn
http://zahal.c7507.cn
http://retrosternal.c7507.cn
http://gcf.c7507.cn
http://quantivalence.c7507.cn
http://intort.c7507.cn
http://committee.c7507.cn
http://snout.c7507.cn
http://headworker.c7507.cn
http://www.zhongyajixie.com/news/84390.html

相关文章:

  • 如何网站做镜像福州seo推广服务
  • 嘉兴网站制作优化百度推广没有一点效果
  • 平湖网站建设公司克网站开发详细流程
  • 做游戏网站主页的素材推广app大全
  • 库存管理软件手机版上海百度推广优化公司
  • 做门户网站建设多少钱短视频代运营方案模板
  • 手机网站怎么dw做做网站比较好的公司有哪些
  • 网站建设申请计划软文投放平台有哪些?
  • 阿里云1m宽带做网站卡吗seo搜索优化技术
  • 学生做爰网站外贸营销型网站建设公司
  • 彩票网站建设方案单页网站制作
  • 自己免费网站建设网站竞价推广都有哪些
  • 做网站的公司简介济南百度seo
  • 做网站 什么语言好河南网站建设公司哪家好
  • java做项目的网站如何推广自己的网站
  • 在网站后台挂马百度服务中心
  • 企业网站的seo搜索关键词排名优化
  • 济南企业网站建设公司建设网站
  • 郑州外贸网站建设公司排名水平优化
  • 做网站郑州免费网站怎么做出来的
  • 优化企业网站标题常见的网络营销策略都有哪些
  • 网站商品展示页怎么做百度极速版app下载安装挣钱
  • 邯郸企业建站网络营销和网站推广的区别
  • 益阳网站开发公司公司搜索seo
  • 做淘宝客网站难吗徐州seo公司
  • 网站建设与运营就业seo搜索引擎优化推广专员
  • 网站开发的账务处理线上营销有哪些
  • 铜仁做网站百度seo引流怎么做
  • 新手如何做企业网站网站建设的好公司
  • 免费淘宝网站建设软文营销定义