- 首页 > 睿知 > it技术 > >
- 用到的库
qs: get请求时转义请求的参数 yarn add qs
emtion: css in js库之一
craco: 自主定义package.json中的脚本, npm run eject的替代方案
craco-less
dayjs 处理日期格式 ## momentjs 已经停止维护
react-query:
react-error-boundary: react 错误边界库
react-helmet: 修改react项目 header中的内容 meta title等
【React Hook学习笔记】encodeURIComponent 转义get请求的参数
encodeURI 转义整个请求的链接
- 封装常用的自定义的hook
useMount:
export const useMount = (callback: (...rest: any) => any) => {
// 依赖项中,加入callback会造成无限循环,这和useCallback &&useMemo有关
useEffect(() => callback(), []);
};
useHttp
useAsync
useDocument
- fetch 不会抛异常
fetch().then().catch()
catch 抛异常的条件:断网,网络不通,请求错误5xx, 4xx 不会抛异常,所以
需要在then中用户根据返回的结果手动抛Promise.reject(...)
- 样式方案
1. 使用antd 组件库
2. css in js库 --> emotion
3. grid布局
4.
- css in js --> 一种组织代码的方式 && css方案
emotion的使用与安装
yarn add @emotion/react @emotion/styled;
编辑器安装插件的支持【styled components && styled jsx】
组件中引入 import styled from '@emotion/styled'
代码组织:
const Container = styled.div`
display: flex;
`
!!!styled.xxxx只能是原生的html标签,那如果引用的是Antd库的组件咋办?==>
const ShadowCard = styled(Card)` // 仅以Card举例
width: 40rem;
`
### Card 替换成对应的需要修饰的 Antd 或者其他UI库组件名
全局样式的
html {
/* rem em */
/*em 相对于父元素的font-size*/
/*rem 相对于根元素html的font-size, r就是root的意思*/
/*16 * 62.5% = 10px*/浏览器默认的font-size: 16
/*1rem === 10px*/
font-size: 62.5%;
// ==> 此时 1rem === 10px
}/*viewport height === vh*/
html body #root .App {
min-height: 100vh;
// 视口的高度
}
- 网格布局
const Container = styled.div`
display: grid;
grid-template-rows: 6rem 1fr 6rem;
grid-template-columns: 20rem 1fr 20rem;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
height: 100vh;
grid-gap: 10rem;
`;
#1. 1fr 自由伸缩
// grid-area 用来给grid子元素起名字
const Header = styled.header`
grid-area: header;
......
`;
const HeaderRight = styled.div``;
const Main = styled.main`
grid-area: main;
`;
const Nav = styled.nav`
grid-area: nav;
`;
const Aside = styled.aside`
grid-area: aside;
`;
const Footer = styled.footer`
grid-area: footer;
`;
grid flex 使用场景
*从内容出发:你先有一组内容(数量一般不固定),然后希望他们均匀的分布在容器中,由内容自己的大小决定占据的空间
*从布局出发:先规划网格(数量一般比较固定),然后再把元素往里填充
- 一维布局 || 从内容出发:flex
- 二维布局 || 从布局出发:grid
- svg的图片以svg的方式渲染
import { ReactComponent as SoftwareLogo } from "assets/software-logo.svg";
- 自定义Error && Loading组件 --> 自定义useAsync统一处理loading&&error
- 错误边界
import React, { Children, ReactNode } from 'react'type ErrorType = {
error: Error | null
}// React.ReactElement JSX的类型
type FallbackRender = (props: ErrorType) => React.ReactElementtype PropsType = {
children: ReactNode,
fallbackRender: FallbackRender
}
// or 利用联合类型
type PropsType2 = React.PropsWithChildren<{fallbackRender: FallbackRender}>export class ErrorBoundary extends React.Component {
state = {error: null}// 当子组件抛出异常,这里会接收到并调用
static getDerivedStateFromError(error: Error) {
return {error} // 自动设置state
}render() {
const {error} = this.state
const { fallbackRender, children} = this.propsif (error) return fallbackRender({error})return children
}
}
- useRef Hook闭包案例
export const useDocumentTitle = (title: string, keepOnUnmount: boolean = true) => {
const oldTitle = document.title
// 页面加载时:oldTitle === 旧title 'React App'
// 加载后:oldTitle === 新titleuseEffect(() => {
document.title = title
}, [title])useEffect(() => {
return () => {
if (!keepOnUnmount) {
// 如果不指定依赖,读到的就是就title
document.title = oldTitle
}
}
}, [])
}const test = () => {
let num = 0;
const effect = () => {
num += 1
const message = `现在的num值: ${num}`
return function unmmount() {
console.log(message)
}
}return effect
}const add = test()
const unmount = add()
add()
add()
unmount() /// 打印几?export const useDocumentTitle2 = (title: string, keepOnUnmount: boolean = true) => {
/**
* 官网:useRef返回一个可变的ref对象,其.current属性被初始化为传入的参数(initialValue)。
* 返回的ref对象在组件的生命周期内保持不变
*/
const oldTitle = useRef(document.title).current;
useEffect(() => {
document.title = title
}, [title])useEffect(() => {
return () => {
if (!keepOnUnmount) {
// 如果不指定依赖,读到的就是就title
document.title = oldTitle
}
}
}, [title, keepOnUnmount])
}
test.tsx
import { useEffect, useState } from "react"export const Test = () => {
const [num, setNum] = useState(0)const add = () => setNum(num + 1)/**
* useEffect中引用的num是 只有页面加载时执行一次,里面形成一个闭包,而其作用域引用的num是页面刚加载时候的值
* 怎么保证里面拿到的值 是新鲜的呢?在effect中 [xxx] 依赖项
*/
useEffect(()=>{
setInterval(() => {
console.log('num in setInterval:', num)
})
}, [])useEffect(() => {
return () => {
console.log(num)
}
}, [])return
{num}
}
推荐阅读