首页 > 其他分享 >浅谈React

浅谈React

时间:2024-07-13 21:56:41浏览次数:8  
标签:count return 浅谈 setCount React num import const

forwardRef和useImperativeHandle的联动使用

import React, { useImperativeHandle, useRef } from "react"
import { forwardRef } from "react"

const CustomInput = forwardRef((props, ref) => {
    const inputRef = useRef<HTMLInputElement>(null)

    useImperativeHandle(ref, () => ({
        focus: () => {
            inputRef.current?.focus()
        }
    }))
    return <div>
        <input ref={inputRef} />
    </div>
})

export default CustomInput

巧用children

  • 一般用法
父组件:

import React from "react"
import Child from './Child'

const CustomInput = () => {
    return <Child>
        <div>hello 靓仔</div>
    </Child>
}

export default CustomInput

子组件:

import React from "react"


const Child = ({
    children
}) => {
    return <div>{children}</div>
}

export default Child
  • 函数用法
父组件:

import React from "react"
import Child from './Child'

const CustomInput = () => {
    return <Child>
        {(arr)=><div>
            {arr.map((v,idx)=>{
                return <div key={idx}>{v}</div>
            })}
            </div>}
    </Child>
}

export default CustomInput

子组件:

import React from "react"


const Child = ({
    children
}) => {
    const arr = [1,2,4,5]
    return <div>{children(arr)}</div>
}

export default Child

useEffect

  • 没有依赖,类似于componentDidMount和componentDidUpdate
import React, { useEffect, useState } from "react"


const Detail = () => {
    const [count, setCount] = useState(1)
    const [num,setNum] = useState(2)
    useEffect(()=>{
        console.log(count,'count',num,'num')
    })
    return <div>
        <div onClick={() => setCount(count + 1)}>add count</div>
        <div onClick={() => setNum(num + 1)}>add num</div>
        <div>count: {count}</div>
        <div>num: {num}</div>
    </div>
}

export default Detail

  • 依赖是个空数组,相当于componentDidMount
import React, { useEffect, useState } from "react"


const Detail = () => {
    const [count, setCount] = useState(1)
    const [num,setNum] = useState(2)
    useEffect(()=>{
        console.log(count,'count',num,'num')
    },[])
    return <div>
        <div onClick={() => setCount(count + 1)}>add count</div>
        <div onClick={() => setNum(num + 1)}>add num</div>
        <div>count: {count}</div>
        <div>num: {num}</div>
    </div>
}

export default Detail

 

 

  • 有依赖,componentDidMount和对应依赖的componentDidUpdate
import React, { useEffect, useState } from "react"


const Detail = () => {
    const [count, setCount] = useState(1)
    const [num,setNum] = useState(2)
    useEffect(()=>{
        console.log(count,'count',num,'num')
    },[num])
    return <div>
        <div onClick={() => setCount(count + 1)}>add count</div>
        <div onClick={() => setNum(num + 1)}>add num</div>
        <div>count: {count}</div>
        <div>num: {num}</div>
    </div>
}

export default Detail

 

 

useEffect和useLayoutEffect

useEffect在渲染后执行,而useLayouEffect是在渲染之前执行

最典型的例子就是实现一个tooltip组件,在性能比较差的情况下,useEffect会先渲染初始状态再更新,而useLayoutEffect会阻塞UI的更新即不会出现组件闪烁的情况~

阻塞代码:

let now = performance.now();
while (performance.now() - now < 100) {
}

useEffect在性能差的情况下会出现以下效果

useContext

依赖注入

父级:
export const ThemeContext = createContext({});
const App = ()=>{

return  <ThemeContext.Provider value={{name:"real hot"}}>
        ......
    </ThemeContext.Provider>
}

 子级:
  const context = useContext(ThemeContext)
  console.log(context)

useState的变动

在react管辖下(react17.x.x)

  • 函数形式

状态能够更改多次,只渲染一次

const handleCount= ()=>{
  setCount(count=>count+1)
  setCount(count=>count+1)
}

  • 对象形式

多次更改状态会被合并成一次更改,即一次生效其他无效,只渲染一次

const handleCount= ()=>{
  setCount(count+1)
  setCount(count+1)
}

在异步任务/原生事件下(react17.x.x)

const handleCount= ()=>{
setTimeout(()=>{
  setCount(count=>count+1)
  setCount(count=>count+1)
})
}

 

版本的演变(React18)

react18之后在异步操作或者react事件中都是批量更新,即多个状态更新合成一次渲染,若需要多次渲染可使用flushsync

const handleCount= ()=>{
  flushSync(()=>{
    setCount(count=>count+1)
  })
  flushSync(()=>{
    setCount(count=>count+1)
  })

}

探索生命周期函数

父子组件生命周期执行顺序

挂载: 

更新: 

卸载: 

错误处理

生命周期方法:

getDerivedStateFromError
componentDidCatch

缺点(没办法捕获):

  • 异步操作
  • 事件处理函数报错
  • 错误边界自己报错 
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

实现一个简单的Message

import ReactDOM from 'react-dom';
import { Modal } from 'antd';
const ToastFn = () => {
let parent = null;
return {
open: function ({ el, container = document.body }) {
// this.destroy();
parent = document.createElement('div');
document.body.appendChild(parent);
ReactDOM.render(<Modal open onCancel={this.destroy}>{el}</Modal>, parent)
},
destroy: function () {
ReactDOM.unmountComponentAtNode(parent);
},
};
};
const Toast = ToastFn();
export default Toast;

标签:count,return,浅谈,setCount,React,num,import,const
From: https://blog.csdn.net/hometowna/article/details/139533379

相关文章

  • 浅谈接口自动化测试
    接口测试大家一定不陌生了,对QA来说也是一项比较基础的技能,并且在现代软件开发中,持续集成已经成为一种不可或缺的实践,所以很多项目中都会做UI自动化、接口自动化的持续集成。在实际工作中,个人感觉接口自动化测试比UI自动化测试性价比要高得多的多,首先接口测试在整个流程......
  • 全栈物联网项目:结合 C/C++、Python、Node.js 和 React 开发智能温控系统(附代码示例)
    1.项目概述本文详细介绍了一个基于STM32微控制器和AWSIoT云平台的智能温控器项目。该项目旨在实现远程温度监控和控制,具有以下主要特点:使用STM32F103微控制器作为主控芯片,负责数据采集、处理和控制逻辑采用DHT22数字温湿度传感器,精确采集环境温湿度数据通过ESP8266WiF......
  • React使用ProComponent建立表单和列表
    ProComponentProComponent基于Antd组件库,进一步封装,成为满足企业级开发需求的组件库。其兼容Antd内容的基础上,对表单列表等内容进行完善,在建立表单等需求中能够提供强大的api以及功能集合AntDesign定义了基础的设计规范,对应也提供了大量的基础组件。但是对于中后台类应用,我们......
  • vue中ref()与reactive(的区别)
    #ref和reactive的区别对比之前先看一下如何使用,它们的使用方法都很简单,也很类似:<template> <div>{{user.first_name}}{{user.last_name}}</div> <div>{{age}}</div></template><script>import{reactive}from'vue'exportdefa......
  • React中使用usePrevious的意义是什么,为啥要用它
    usePrevious钩子exportfunctionusePrevious<T>(value:T):T|undefined{constref=useRef<T>();useEffect(()=>{ref.current=value;},[value]);returnref.current;}注:更多好用的性能钩子网站推荐:https://react-hooks-library.vercel.ap......
  • 日常工作中需要避免的9个React坏习惯
    前言React是前端开发领域中最受欢迎的JavaScript库之一,但有时候在编写React应用程序时,可能陷入一些不佳的习惯和错误做法。这些不佳的习惯可能导致性能下降、代码难以维护,以及其他问题。在本文中,我们将探讨日常工作中应该避免的9个坏React习惯,并提供相关示例代码来说明这些问题以......
  • 日常工作中需要避免的9个React坏习惯
    前言React是前端开发领域中最受欢迎的JavaScript库之一,但有时候在编写React应用程序时,可能陷入一些不佳的习惯和错误做法。这些不佳的习惯可能导致性能下降、代码难以维护,以及其他问题。在本文中,我们将探讨日常工作中应该避免的9个坏React习惯,并提供相关示例代码来说明这些......
  • 浅谈HTTP中Get与Post的区别
    Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/......
  • react 实现前端发版监测
    先说下前端发版流程1.前端打包输出产物/dist文件2.删除远程服务下打包的旧代码3.将打包参物/dist文件copy到远程服务器目录4.重启服务器问题1在步骤2,3,4中用户访问目标服务器会报JS错误,正常情况打开网页的控制面板会看下报错信息`Failedtofetchdynamicallyimp......
  • 浅谈vite
    在开发环境并不做打包,采用es6中的module进行引入;具体它是怎么做?pleasecontinuetolookdown~~~编译服务、esbild预购建、rollup打包。npmrundevvite会跑一个开发服务;const{createServer}=awaitimport('./server');try{constserver=awaitcreateServer({......