React常见的一些坑

news2024/11/19 17:24:17

文章目录

  • 两个基础知识
    • 1. react的更新问题, react更新会重新执行react函数组件方法本身,并且子组件也会一起更新
    • 2. useCallback和useMemo滥用
    • useCallback和useMemo要解决什么
    • 3. react的state有个经典的闭包,导致拿不到最新数据的问题.
    • 常见于useEffect, useMemo, useCallback
    • 4. 副作用方案
    • 总结

两个基础知识

1. react的更新问题, react更新会重新执行react函数组件方法本身,并且子组件也会一起更新

在这里插入图片描述

2. useCallback和useMemo滥用

useCallback和useMemo要解决什么

React.memo包装组件
React.useCallback包裹传递子组件函数

对于传递给组件的对象是固定不变的,和数据没有关系的.
需要将固定变量放在函数外层

React.useMemo: 当你给子组件的对象是和组件数据有关的, 也就是做一个计算属性时候
, 采用useMemo

3. react的state有个经典的闭包,导致拿不到最新数据的问题.

常见于useEffect, useMemo, useCallback

在这里插入图片描述

在这里插入图片描述

4. 副作用方案

在这里插入图片描述

在这里插入图片描述

App.jsx

import React, { useState, useRef, useEffect } from 'react'
import Filter from './components/Filter';
import Pagers from './components/Pagers';

import './App.css'

// * 如果这个对象是固定不变的,和state数据无关系, 需要提到组件外侧
const obj = {
  a:'cccc'
}

// useRef, 副作用方案
// 如果有一个state数据, 需要传递给子组件时候
// 建议把state数据定义为ref
function App() {
  const [count, setCount] = useState(0)
  const [filterData, setFilterData] = useState('')
  const [pageData, sePageData] = useState('')

  // useRef: 
  // 当有一个变量, 当这个变量不想被外部获取, 不需要写依赖
  // 并且还想获取state最新值, 此时,需要将state变为ref
  // useRef定义的变量【不会造成视图更新】
  // const filterData = useRef('')
  // const setFilterData = React.useCallback((val)=>{
  //   filterData.current = val
  // }, [])

  // 准备一个请求接口的方法给筛选栏
  // 再次更新,就会重新执行, 等于又在内存中新建了一个getList方法
  // 第一次渲染->getList 创建 1001 第二次->1002
  //1.  * useCallback并不是有方法一定要包裹, 只有当这个方法给子组件的时候才有

  // const getList = React.useCallback((page)=>{
  //   console.log('=item=====');
  //   // console.log(item);
  //   // *2.  useCallback, useEffect, useMemo方法. 如果用到state数据
  //   // * 一定要把state数据写在第二个数组中, 否则拿不到新数据

  //   // 改为useRef方式,  搜索栏更新,不会造成page更新
  //   console.log(count, filterData, page);
  // }, [count, filterData])


  // 方法3: 使用useEffect监听子组件变化, 不将getList方法传递子组件
  useEffect(() => {
    console.log(count, filterData, pageData);
  }, [count, filterData, pageData])
  

  // * 3. React.useMemo: 当你给子组件的对象是和组件数据有关的, 也就是做一个计算属性时候
  return (
    <>
 
      <h1>Vite + React</h1>
      <div className="card">
        父组件本身:
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
      </div>
      <div>
        筛选栏:
        <Filter
        //  config={obj}
         filterData={filterData}
         setFilterData={setFilterData}
        //  getList={getList}
         />
      </div>
      <div className="read-the-docs">
        <Pagers 
          sePageData={sePageData}
          //  getList={getList}
        />
      </div>
    </>
  )
}

export default App

Pagers.jsx

import React from "react";

function Pagers(props) {
  console.log("pager render");
  const { sePageData } = props;
  return (
    <div className="Pager">
      {[1, 2, 3, 4, 5].map((i) => {
        return (
          <div
            key={i}
            onClick={() => {
              sePageData(i);
            }}
          >
            {i}
          </div>
        );
      })}
    </div>
  );
}

export default React.memo(Pagers);

Filter.jsx

import React, { useState } from 'react'


function Filter(props) {
  console.log('Filter render---');

  const { setFilterData } = props
  const value = React.useRef('')
  return (
    <>
     <input onChange={
      (e)=>{
        value.current = e.target.value
      }
     } ></input>
     <button  onClick={()=> setFilterData(value.current)}>搜索</button>
    </>
  )
}

export default React.memo(Filter)

总结

小结一下:
React 函数式组件会在state/props/context/父组件重新渲染时,重新执行函数,
为避免不必要的性能消耗(函数重新定义,某些值重新计算等等),减少重新渲染(或者重新执行函数式组件),需要控制props + 配合react.memo
控制props :

  1. 用useCallback暂存函数(注意用到state时要用好第二个参数)、useMemo避免复杂运算重复执行
  2. 用Ref(非受控组件)获取不需要渲染,但又是最新的值
  3. 不变的值写在函数式组外,避免重复创建
  4. jsx里尽量不写字面量、匿名函数

// useRef:
// 当有一个变量, 当这个变量不想被外部获取, 不需要写依赖
// 并且还想获取state最新值, 此时,需要将state变为ref
// ** useRef定义的变量【不会造成视图更新】**
// const filterData = useRef(‘’)
// const setFilterData = React.useCallback((val)=>{
// filterData.current = val
// }, [])

// 注意:useRef定义的变量【不会造成视图更新】,而state变量会视图更新, 也会被添加到依赖项, 会影响子组件更新

  1. 使用方案3, 使用useEffect监听子组件变化, 不将getList方法传递子组件
    ,只用将修改父组件数据的方法传递到子组件. 在父组件通过副作用更新

  2. 技巧4, 当数据只在子组件中使用时候, 而不会在页面展示时,
    需定义为useRef变量,(在页面展示时定义为state变量).

定义在组件内部, 在点击确定时候, 将数据更新到父组件, 修改时用.current修改

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1791734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Crosslink-NX器件应用连载(11): 图像(数据)远程传输

作者&#xff1a;Hello&#xff0c;Panda 大家下午好&#xff0c;晚上好。这里分享一个Lattice Crosslink-NX器件实现图像或数据&#xff08;卫星数据、雷达数据、ToF传感器数据等&#xff09;远程传输的案例&#xff08;因为所描述的内容颇杂&#xff0c;晒图不好晒&#xff…

618数码好物推荐!精选便宜又实用的数码产品推荐!

着618购物盛宴的脚步日益临近&#xff0c;你是否已经锁定了心仪的宝贝&#xff1f;那些曾让你心动不已的数码产品&#xff0c;现在正是以最低价收入囊中的绝佳时机。618不仅是一场购物狂欢&#xff0c;更是各大电商平台竞相推出优惠政策的盛宴。为了满足大家的需求&#xff0c;…

C语言笔记第13篇:自定义类型(联合union和枚举enum)

1、联合体 1.1 联合体类型的声明 像结构体一样&#xff0c;联合体也是由一个或多个成员构成&#xff0c;这些成员可以是不同的类型。 但是编译器只为最大的成员分配足够的内存空间&#xff0c;联合体的特点是所有成员共用一块内存空间&#xff0c;所以联合体也叫&#xff1a…

HTML+CSS+JS实现2048经典小游戏(附完整源码)

2048 小游戏的目标是通过合并数字单元格&#xff0c;最终在 4x4 的棋盘上创建一个值为 2048 的单元格。 一、预览效果 二、程序源码 html代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"…

Vue——组件数据传递与props校验

文章目录 前言组件数据传递的几种类型简单字符串类型数据专递其他类型数据(数字、数组、对象)传递注意事项 数据传递值校验限定数据类型 type给定默认值 default指定必选项 required 前言 组件与组件之间并不是完全独立的&#xff0c;他们之间可以进行一些数据的传递操作。传递…

宇宙探索:假如把银河系缩小到一个电子那么小,那宇宙会有多大?

“你知道银河系有多大吗?”“我们可以看到的宇宙有多大呢?”“那么假如把银河系缩小到一个电子那么小&#xff0c;那么我们可以看到的宇宙会有多大呢?”这样一个看似简单的问题却没有一个简单的答案&#xff0c;那么蕴藏其中的玄机是什么? 一、光是无法照亮宇宙的角落。 从…

思维,1209G1 - Into Blocks (easy version)

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - 1209G1 - Codeforces 二、解题报告 1、思路分析 考虑&#xff1a; 最终状态为若干段相同数字&#xff0c;且任意两段数字不同 每个数字出现的最左下标和最右下标构成一个区间 连锁反应—…

月薪12万招聘AI人才,AI已成为大公司的竞争,小公司难以生存

前言 AI已经成为了时代的风口&#xff0c;这个风口的风力有多大呢&#xff1f; 一个月12-20万。 对&#xff0c;一个月120000-200000元&#xff01; 如果说&#xff0c;步入2024年最火的是什么&#xff0c;那一定就是ChatGPT所引领的开放式AI了&#xff0c;这个东西有多火呢…

AI绘画入门指南!一遍就会!AI绘画Stable Diffusion新手入门教程

我们尝试了一段时间Midjourney&#xff0c;发现其对图片的可控性较弱。于是研究起了Stable Diffusion。 SD的主要优势在于开源&#xff0c;因为开源会有很多无私的大佬分享自己的模型、插件及脚本等&#xff0c;让SD有了更丰富的扩展。在画面统一性和更像本人方面要比MJ容易实…

C++之虚函数与多态

1、多态 前面三种称为静态绑定&#xff08;静态多态&#xff09;&#xff0c;最后面的虚函数&#xff0c;则称为动态绑定&#xff08;动态多态&#xff09;。 2、静态绑定与动态绑定 要实现动态绑定&#xff0c;就必须使用虚函数。 3、虚函数 只有当你在&#xff1a;基类的指…

Mysql 常用命令 详细大全【分步详解】

1、启动和停止MySQL服务 // 暂停服务 默认 80 net stop mysql80// 启动服务 net start mysql80// 任意地方启动 mysql 客户端的连接 mysql -u root -p 2、输入密码 3、数据库 4、DDL&#xff08;Data Definition Language &#xff09;数据 定义语言, 用来定义数据库对象(数…

手机怎么压缩图片?通过三种压缩操作

手机怎么压缩图片&#xff1f;在智能手机日益普及的今天&#xff0c;拍照分享已成为日常生活的一部分。然而&#xff0c;高质量的照片往往占用较大的存储空间&#xff0c;且在网络上传输时速度较慢。那么&#xff0c;如何在手机上压缩图片呢&#xff1f;本文将介绍三种实用的手…

C/C++图形库Easyx的使用教学

绘制简单的图形窗口 学会创建图形化窗口 包含头文件 graphics.h包含已被淘汰的函数easyx.h包含最新的函数 两个函数就可以创建窗口 Initgraph&#xff08;&#xff09;函数的定义 图形窗口的创建 #include<graphics.h>int main() {initgraph(800, 600);while (1);…

90%国际3A游戏发行商的首选,一文揭秘语音驱动面部动画生成技术!

在科技迅猛发展的时代&#xff0c;AI 正以破竹之势重塑着我们的世界。从激烈的“百模大战”到应用层生态的“百花齐放”&#xff0c; AIGC 产业迎来了快速增长的爆发期。AIGC 引领的创新应用&#xff0c;正推动着包括动漫游戏产业在内的各行各业加速升级。随着 AIGC 技术的不断…

SVN安装详细教程

&#x1f4d6;SVN安装详细教程 ✅1. 下载✅2. 安装✅3. 使用 ✅1. 下载 官方地址&#xff1a;https://tortoisesvn.net/downloads.html 123云盘地址&#xff1a;https://www.123pan.com/s/4brbVv-rsoWA.html ✅2. 安装 双击TortoiseSVN-1.14.6.29673-x64-svn-1.14.3.msi安装…

Kafka消费者api编写教程

1.基本属性配置 输入new Properties().var 回车 //创建属性Properties properties new Properties();//连接集群properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"node1:9092,node2:9092");//反序列化properties.put(ConsumerConfig.KEY_DESERIALIZER_CL…

云端狂飙:Django项目部署与性能优化的极速之旅

Hello&#xff0c;我是阿佑&#xff0c;这次阿佑将手把手带你亲自踏上Django项目从单机到云端的全过程&#xff0c;以及如何通过Docker实现项目的无缝迁移和扩展。不仅详细介绍了Docker的基本概念和操作&#xff0c;还深入探讨Docker Compose、Swarm和Kubernetes等高级工具的使…

车辆路径规划之Dubins曲线与RS曲线简述

描述 Dubins和RS曲线都是路径规划的经典算法&#xff0c;其中车辆运动学利用RS曲线居多&#xff0c;因此简单介绍Dubins并引出RS曲线。 花了点时间看了二者的论文&#xff0c;并阅读了一个开源的代码。 Dubins曲线 Dubins曲线是在满足曲率约束和规定的始端和末端的切线&#…

【python】IndexError: Replacement index 1 out of range for positional args tuple

成功解决“IndexError: Replacement index 1 out of range for positional args tuple”错误的全面指南 一、引言 在Python编程中&#xff0c;IndexError: Replacement index 1 out of range for positional args tuple这个错误通常发生在使用str.format()方法或者f-string&am…

网络编程 —— Http使用httpClient实现页面爬虫

先去找类型的a标签 取出图片所在网址 取出https://desk.3gbizhi.com/deskMV/438.html 搭建Form界面 Http类 public static HttpClient Client { get; } static Http() {HttpClientHandler handler new HttpClientHandler();//处理消息对象//ServerCertificateCustomValidat…