关于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>
    }

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理