乐趣区

关于react.js:React-Hook学习笔记

  1. 用到的库

    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 等
    

    encodeURIComponent 本义 get 申请的参数
    encodeURI 本义整个申请的链接🔗

  2. 封装罕用的自定义的 hook

    useMount:
    export const useMount = (callback: (...rest: any) => any) => {
        // 依赖项中,退出 callback 会造成有限循环,这和 useCallback &&useMemo 无关
      useEffect(() => callback(), []);
    };
    useHttp
    useAsync
    useDocument
  3. fetch 不会抛异样

    fetch().then().catch()
    catch 抛异样的条件:断网,网络不通, 申请谬误 5xx, 4xx 不会抛异样,所以
    须要在 then 中用户依据返回的后果手动抛 Promise.reject(...)
  4. 款式计划

    1. 应用 antd 组件库
    2. css in js 库 --> emotion 
    3. grid 布局
    4. 
  5. 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.xx  xx 只能是原生的 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; // 视口的高度}
    
  6. 网格布局

    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 应用场景
    * 从内容登程:你先有一组内容 (数量个别不固定), 而后心愿他们平均的散布在容器中,由内容本人的大小决定占据的空间
    * 从布局登程:先布局网格 (数量个别比拟固定),而后再把元素往里填充

    1. 一维布局 || 从内容登程:flex
    2. 二维布局 || 从布局登程:grid
  7. svg 的图片以 svg 的形式渲染

    import {ReactComponent as SoftwareLogo} from "assets/software-logo.svg";
    
  8. 自定义 Error && Loading 组件 –> 自定义 useAsync 对立解决 loading&&error
  9. 谬误边界

    import React, {Children, ReactNode} from 'react'
    
    type ErrorType = {error: Error | null}
    
    // React.ReactElement JSX 的类型
    type FallbackRender = (props: ErrorType) => React.ReactElement
    
    type PropsType = {
        children: ReactNode,
        fallbackRender: FallbackRender
    }
    // or 利用联结类型
    type PropsType2 = React.PropsWithChildren<{fallbackRender: FallbackRender}>
    
    export class ErrorBoundary extends React.Component<PropsType2, ErrorType> {state = {error: null}
    
        // 当子组件抛出异样,这里会接管到并调用
        static getDerivedStateFromError(error: Error) {return {error} // 主动设置 state
        }
    
        render() {const {error} = this.state
            const {fallbackRender, children} = this.props
    
            if (error) return fallbackRender({error})
    
            return children
        }
    }
  10. useRef Hook 闭包案例

    export const useDocumentTitle = (title: string, keepOnUnmount: boolean = true) => {
        const oldTitle = document.title
        // 页面加载时:oldTitle === 旧 title 'React App'
        // 加载后:oldTitle === 新 title
    
        useEffect(() => {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 <div>
            <button onClick={add}>add</button>
            <p>{num}</p>
        </div>
    }
退出移动版