React常见的一些坑

文章目录

  • 两个基础知识
    • 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 (<divkey={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 } = propsconst 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.mzph.cn/diannao/21106.shtml

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

相关文章

【激光雕刻机上位机的成品软件】核心功能 - 参考wecreat

Software | WeCreat MakeIt! https://wecreat.com/pages/software 体验软件如上&#xff0c;自行下载体验。 价格5W&#xff0c;本人为 wecreat 创立之初上位机软件开发的核心员工&#xff0c;详细内容私信我。 由于该公司快3个月未给我竞业补偿了&#xff0c;对我不仁那我…

Anaconda创建python环境默认C盘,如何修改路径

文章目录 前言解决方案1.找到Anaconda的根目录2. 找到根目录文件夹&#xff0c;右键-属性-安全 测试-重新创建新的python环境 前言 使用 Anaconda创建python环境&#xff0c;默认在C盘。 如何修改到别的路径呢&#xff1f; base环境 是安装 Anaconda是安装的默认环境&#x…

设计模式——结构型模式——责任链模式

责任链模式简介 责任链模式&#xff0c;又名职责链模式&#xff0c;为了避免请求发送者与多个请求处理者耦合在一起&#xff0c;将所有请求处理者通过前一对象记住其下一个对象的引用而成一条链&#xff1b;当有请求发生时&#xff0c;可将请求沿着这条链传递&#xff0c;传递过…

python dlib 面部特征点检测

运行环境macos m2芯片 Python 3.11.7&#xff0c;python3.9都能通过&#xff0c;windows系统应该也是一样的效果 import dlib import cv2 import matplotlib.pyplot as plt# Load the image image_path path_to_your_image.jpg # Replace with the path to your image image…

QT 信号和槽 一对多关联示例,一个信号,多个槽函数响应,一个信号源如何绑定多个槽函数

在窗体里放置一个单行文本编辑控件&#xff08;QLineEdit&#xff09;、一个标签控件&#xff08;QLabel&#xff09;和一个文本浏览控件&#xff08;QTextBrowser&#xff09;&#xff0c;在单行文 本编辑控件里的文本被编辑时&#xff0c;标签控件和文本浏览控件都会同步显示…

网安速成之选择题(详细解析版)

网安速成之选择题 单选多选 单选 密码学的目的是&#xff08; C &#xff09;。 A. 研究数据压缩 B. 研究数据解密 C. 研究数据保密 D. 研究漏洞扫描 密码学的目的是研究数据加密&#xff0c;保证数据的机密性 数据机密性安全服务的基础是&#xff08; D &#xff09;。 A. 数…

C++ 的 Tag Dispatching(标签派发) 惯用法

目录 1.概述 2.标准库中的例子 3.使用自己的 Tag Dispatching 3.1.使用 type traits 技术 3.2.使用 Type_2_Type 技术 4.Tag Dispatching的使用场景 5.总结 1.概述 一般重载函数的设计是根据不同的参数决定具体做什么事情&#xff0c;编译器会根据参数匹配的原则确定正确…

面试题 - Java基础个人总结

1、Java语言特点/优势 1.1、什么是面向对象编程 2、Java的八种基本数据类型 2.1、为什么要有基本数据类型的封装类 2.2、Java自动装箱和拆箱 笔试题-1 笔试题-2 2.3、为什么浮点数运行时&#xff0c;会有丢失精度的风险&#xff1f; 2.4、补充知识&#xff1a; 3、重载…

WP All Import插件

使用 WP All Imports 插件并将亚马逊产品集成到 WooCommerce 网站中。在您的网站上&#xff0c;他们可以添加到购物车...然后一旦他们按下结帐&#xff0c;他们就会被发送到亚马逊进行付款 WP All Import 是一个强大的WordPress插件&#xff0c;它允许用户从XML或CSV文件中导入…

封装uview-plus上传组件up-upload,支持v-model绑定

痛点 vue上传组件拿到了一般无法直接使用&#xff0c;需要对其上下传的接口按照业务进行处理及定制。本次拿到的uview-plus也是一样&#xff0c;对其上传组件up-upload进行封装&#xff0c;令其更方便开发 目标 封装希望达到的目标&#xff0c;就是实现v-model的绑定。令其支…

字符串-将str1编辑成str2所需最小代价(hard)

一、题目描述 二、解题思路 该题目使用动态规划的思想来解决问题 刚开始我还在想&#xff0c;删除添加的操作可以等价为替换操作&#xff0c;如果替换操作的Cost大于删除添加组合操作的Cost之和就需要把 rcdcic。 但是在动态规划中&#xff0c;如果对三种不同的操作方式进行…

【Centos7】解决 CentOS 7 中出现 “xx: command not found“ 错误的全面指南

【Centos7】初探xx:command not found解决方案 大家好 我是寸铁&#x1f44a; 【Centos7】解决 CentOS 7 中出现 “xx: command not found” 错误的全面指南✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 经常有小伙伴问我&#xff0c;xx:command not found怎么办&#xff1…

Spring原理-IOC和AOP

概述 在此记录spring的学习内容。spring官网&#xff1a;https://spring.io/ 概念故事 从前&#xff0c;在Java的大森林中&#xff0c;有一片神奇的土地&#xff0c;名叫"Spring"。这片土地上生长着各种美丽而强大的植物&#xff0c;它们分别象征着Spring框架中的…

1.1 寻找灵感:怎样像艺术家一样去看待这个世界

“你是从哪里获取到这些创作灵感的&#xff1f;” 当每一个艺术家被问到这个问题时&#xff0c;只有诚实的艺术家会回答&#xff1a; “这是我偷窃的” 怎样像艺术家一样去看待这个世界呢&#xff1f; 你首先需要弄明白什么是值得你偷窃的&#xff0c;然后你才能继续接下来…

如何在一台电脑上安装多个版本的JDK并且切换使用?

如何在一台电脑上安装多个版本的JDK并且切换使用&#xff1f; 文章目录 如何在一台电脑上安装多个版本的JDK并且切换使用&#xff1f;1.目录管理2.下载JDK3.配置环境变量4. 验证 1.目录管理 我们需要首先对不同版本的JDK进行版本管理&#xff0c;如下所示&#xff0c;我在C盘路…

# linux 系统下 切换 root 用户时出现 authentication failure 的解决办法

linux 系统下 切换 root 用户时出现 authentication failure 的解决办法 1、问题分析&#xff1a; 切换 root 用户时出现 authentication failure&#xff0c;意思即 “身份验证失败”&#xff0c;这是由于新安装的系统&#xff0c;可能没有给 root 用户设置密码。 2、解决方…

算法(二)二分查找

文章目录 二分查找简介实现方式循环方式递归方式 经典例子 二分查找简介 二分查找&#xff08;binary search&#xff09;算法&#xff0c;也叫折半算法。二分查找是针对有序的数据集合的查找办法&#xff0c;如果是无序的数据结合就使用遍历。二分查找之所以快速&#xff0c;…

OWASP top10--SQL注入(四、sqlmap安装及使用)

目录 sqlmap工具安装&#xff1a; 工具说明&#xff1a; 主要功能特性包括&#xff1a; 基本使用示例&#xff1a; 先下载python2.7.9版本 sqlmap运行 sqlmap工具使用 -u -r –-levelLEVEL扫描深度级别 --riskRISK 执行测试的风险 -threads 线程数 -batch-smart智能…

鸿蒙开发加强2

快速创建一个符合长度的数组 空数组 Array.from({length: 200}) // 200的长度的空数组 场景&#xff1a;只确定长度&#xff0c;不确定内容的情况 State 状态装饰器 》增强功能 数据变化了 可以引起页面的重新渲染 没有State修饰的变量&#xff0c;不会引起UI的刷新渲染 加…

fintuning chatglm3

chatglm3介绍 ChatGLM3-6B 是 ChatGLM 系列最新一代的开源模型&#xff0c;在保留了前两代模型对话流畅、部署门槛低等众多优秀特性的基础上&#xff0c;ChatGLM3-6B 引入了如下特性&#xff1a; 更强大的基础模型&#xff1a; ChatGLM3-6B 的基础模型 ChatGLM3-6B-Base 采用…