react—Hook(2)

news2024/10/7 14:25:24

6. useMemo—似计算属性

useMemo和useCallback的作用十分类似,只不过它允许记住任何类型的变量(useCallback只记住函数)。当改变其他变量时,普通函数都会运行,它返回的结果并没有改变。这个时候就可以使用useMemo将函数的返回值缓存起来。用来优化代码。 

import React, { useState } from "react";

export default function App() {
  let [msg, setMsg] = useState("hello");
  let [n, setN] = useState(2);
  // 求变量(数字)是否为素数
  let fn = (n) => {
    console.log("计算素数", n);
    n = parseInt(n);
    if (n <= 3) {
      return n > 1;
    }
    for (let i = 2; i < n; i++) {
      if (n % i === 0) {
        return false;
      }
    }
    return true;
  };
  return (
    <div>
      <h2>App</h2>
      {<p>{n}是---{fn(n) ? "素数" : "非素数"}</p>}
      <button onClick={() => setN(13327)}>changeN</button>
      <p>{msg}</p>
      <button onClick={() => setMsg("world")}>changeMsg</button>
    </div>
  );
}

解决办法:useMemo来记录函数

// 添加
  let sushu = useMemo(() => {
    let fn = (n) => {
      console.log("计算素数", n);
      n = parseInt(n);
      if (n <= 3) {
        return n > 1;
      }
      for (let i = 2; i < n; i++) {
        if (n % i === 0) {
          return false;
        }
      }
      return true;
    };
    return fn(n);
  }, [n]);
}
// 使用
<p>{n}---{sushu ? "素数" : "非素数"}</p>

 补充点:react中,为什么组件return出来的虚拟模板对象要加小括号

答:在js语法中函数内部的return的用法

        不写 默认函数调用完毕 生成undefined

        写数据直接量

        写表达式,表达式执行结果作为函数的返回值

        return后面不写 <==> 生成undefined

        return语法注意点:必须写在return后面,不能换行(因为js语法中换行代表语句结束)

所以,如果不加小括号,且换行了,js语法就默认换行为语句结束,返回undefined,而不是返回整个模板。

7. 受控组件—似双向数据绑定

非受控组价:输入框内容为只读,不能手动修改,只能用代码改。

import React, { useState } from "react";

export default function Box() {
  let [email, setEmail] = useState("222");
  let login = () => {
      console.log(email);
      setEmail("6666");
  };
  return (
    <div>
      <h3>Box</h3>
      <input type="text" value={email} />
      <button onClick={login}>get</button>
    </div>
  );
}

受控组件:类似双向数据绑定。onChange事件 + event.target.value

import React, { useState } from "react";

export default function Box() {
  let [email, setEmail] = useState("222");
  let login = () => {
    console.log(email);
  };
  return (
    <div>
      <h3>Box</h3>
      <input type="text" value={email} onChange={()=>setEmail(event.target.value)} />
      <button onClick={login}>get</button>
    </div>
  );
}

 8. useContext—多层状态传递

1. 定义

允许在父级组件和底下任意层次的子组件之间传递状态。在函数组件中使用useContext来使用。Context。

2. 方法

创建上下文时,需要将这个ctx单独放在一个js文件中,要使用上下文的就导入进去。使用React.createContext来创建。

import React from "react";
let ctx = React.createContext({})
export default ctx;

父组件提供: <ctx.Provider value={{ 提供的对象 }}></ctx.Provider>

后代组件使用:let obj = useContext(ctx); <h3>Box--{obj.age}</h3>

// App父组件
import React, { useState } from 'react'
import ctx from './ctx.js';
import Box1 from "./Box1.jsx";
import Box2 from "./Box2.jsx";
export default function App() {
  let [msg, setMsg] = useState('hello');
  // ctx.Provider是一个组件
  return (
    <ctx.Provider value={[msg, setMsg]}>
      <div>
        <h2>App--{msg}</h2>
        <Box1></Box1>
        <Box2></Box2>
      </div>
    </ctx.Provider>
  );
}
// Box1子组件
import React, { useContext } from 'react'
import ctx from "./ctx.js";
import Box11 from "./Box11.jsx";

export default function Box1() {
    let [msg, setMsg] = useContext(ctx);
    let chengeMsg = () => {
        setMsg('world')
    };
  return (
    <div>
      <h3>Box1---{msg}</h3>
      <Box11></Box11>
      <button onClick={chengeMsg}>chengeMsg</button>
    </div>
  );
}

// Box11 孙组件
import React, { useContext } from 'react'
import ctx from "./ctx.js";

export default function Box11() {
    let [msg, setMsg] = useContext(ctx);
  return (
      <div>Box11--{msg}</div>
  )
}

// Box2组件 和Box1同级
import React, { useContext } from "react";
import ctx from "./ctx.js";

export default function Box2() {
  let [msg, setMsg] = useContext(ctx);
  return (
    <div>
      <h3>Box2---{msg}</h3>
    </div>
  );
}

上面案例可以实现子组件Box修改父组件App传来的值,并属性页面中所有用到msg的组件。

3. 提供多个上下文时

父组件提供多个数据时,可以使用嵌套来实现(只需要把上下文创建并引入即可),也可以把多个上下文放在同一个上下文中,需要使用哪个状态就通过点语法来取。比如:

// App父组件
import React, { useState } from 'react'
import ctx from './ctx.js'
import ctx2 from "./ctx2.js";
import ctx3 from "./ctx3.js";
import Box1 from "./Box1.jsx"
import Box2 from "./Box2.jsx"
import Box3 from "./Box3.jsx"
export default function App() {
  // let [state, setSate] = useState({cardata:{ title: "电脑", id: 21 },userdata:{ name:"rosy"}})
    let [age, setAge] = useState(33);
    let [msg, setMsg] = useState({ name: "jack" });
  return (
    <ctx2.Provider value={[msg, setMsg]}>
      <ctx.Provider value={[age, setAge]}>
        <div>
          <h2>App--{age}</h2>
          <Box1></Box1>
          <Box2></Box2>
        </div>
      </ctx.Provider>
    </ctx2.Provider>
  );
}
// Box1
import React from 'react'
import Box11 from "./Box11.jsx"
export default function Box1() {
  return (
    <div>
        <h2>Box1</h2>
        <Box11></Box11>
    </div>
  )
}
// Box11 孙组件
import React,{useContext} from 'react'
import ctx2 from './ctx2.js'
export default function Box11() {
      let [msg, setMsg] = useContext(ctx2);
  return (
    <div>Box11--{msg.name}</div>
  )
}

// Box2子组件
import React, { useContext } from "react";
import ctx from "./ctx.js";

export default function Box2() {
  let [age, setAge] = useContext(ctx);
  return (
    <div>
      <h3> Box2--{age}</h3>
    </div>
  );
}

当一个函数组件使用了useContex时,它就订阅了这个ctx的变化,这样当ctx.Provider的value发生变化的时,这个组件就会被重新渲染。上面有介绍,当有多个上下文时可以使用同一个ctx里面,而不同的子组件可能只关心该ctx的某一部分状态,当ctx里面的任意值发生变化的时候,无论这些组件用不用到这些数据它们都会被重新渲染,这样会造成无用渲染,影响性能。接下来介绍三种解决无用渲染的方法

9. React.memo

1. 拆上下文

2. useMemo

不需要用到上下文的函数用useMemo来缓存,写上依赖项。

import React, { useContext, useMemo, useState } from "react";
import ctx from "./ctx";

export default function Box3() {
    let [state, setSate] = useContext(ctx)
    let [n, setn] = useState(100)
    
    return useMemo(() => {
        console.log("刷新模板--只有数据变化才会刷新")
        return (
            <div>
                <h2>Box3</h2>
                <p>{state.userdata.name}</p>
            </div>
        )
    }, [state.userdata.name]);
}

3. React.memo

import React, { useContext, useMemo, useState } from "react";
import ctx from "./ctx";

let Box = React.memo(({ userinfo }) => {
  console.log("刷新模板--无用渲染");
  return (
    <div>
      <h2>box3</h2>
      <p>{userinfo}</p>
    </div>
  );
});
export default function Box3() {
  let [state, setSate] = useContext(ctx);

  return <Box userinfo={state.userdata.name}></Box>;
}

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

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

相关文章

MFC 单文档模式

Doc类利用自带框架存数据 void CCADDoc::Serialize(CArchive& ar) {if (ar.IsStoring()){// TODO: 在此添加存储代码//保存数据到文件ar << m_nShapeCount;for (int i 0; i < m_arrShapes.GetSize(); i){CShape* pShape NULL;pShape (CShape*)m_arrShapes[i];…

如何在大背景下降本增效,构建超大规模存储架构?

在日新月异的大数据服务不断涌现的今天&#xff0c;我们可以看到作为数据基础底座的存储服务面临了越来越多的复杂环境和需求的挑战。无论是离线大数据存储&#xff0c;还是在线 KV 类存储&#xff0c;都服务了越来越多的数据应用场景。存储业务形态的多样化&#xff0c;催生了…

linux centos8下安装redis6.2.12

一.下载安装包并解压 Download | Redis 解压操作 tar -zxvf redis-6.2.12.tar.gz 二.进入到redis-6.2.12中 cd redis-6.2.12 三.预编译make到本地 四.创建文件: mkdir -p /opt/redis,最后将redis安装到opt/redis目录中去 五.安装到指定目录: make install PREFIX/opt/redis…

Android 支持 lhdc

LHDC全称Low-Latency Hi-Definition Audio Codec&#xff0c;是一种高音质蓝牙编解码方案&#xff0c;由台湾厂商 Savitech 盛微先进科技开发。先看下介绍 这块不涉及音频&#xff0c;只有蓝牙&#xff0c;因为音频的codec是由台湾厂商 Savitech 盛微先进科技开发的&#xff0…

信息化项目生命周期类型的特点与管理方法论

目录 一、预测型生命周期 二、迭代型生命周期 三、增量型生命周期 四、适应型生命周期 五、混合型生命周期 六、各生命周期之间的差异点 七、项目管理五大过程组 八、适应型项目中过程组之间的关系 九、项目管理十大知识领域 十、项目管理八大绩效域 十一、价值交付系统 一、预…

立体记录留住精彩瞬间,推荐录屏软件给你

在如今数字化时代&#xff0c;电脑录屏软件成为越来越多人必备的工具之一。不论是教学、演示、游戏录制还是内容创作&#xff0c;录屏软件能够帮助我们捕捉屏幕上的活动并将其保存为高质量的视频文件。然而&#xff0c;在众多的选择中&#xff0c;我们该如何寻找一款适合自己需…

C#核心知识回顾——10.List、Dictionary、数据结构

1.List List<int> list new List<int>(); List<String> strings new List<String>();//增list.Add(0);list.Add(1);List<int> ints new List<int>();ints.Add(0);list.AddRange(ints);//插入list.Insert(0, 1);// 位置0插入1//删//1.移…

Impala3.4源码阅读笔记(五)统计信息

前言 本文为笔者个人阅读Apache Impala源码时的笔记&#xff0c;仅代表我个人对代码的理解&#xff0c;个人水平有限&#xff0c;文章可能存在理解错误、遗漏或者过时之处。如果有任何错误或者有更好的见解&#xff0c;欢迎指正。 基本信息 在Impala中&#xff0c;Stats记录…

【Vuejs】1732- 详细聊一聊 Vue3 依赖注入

&#x1f449; 「相关文章」 深入浅出 Vue3 自定义指令详细聊一聊 Vue3 动态组件6 个你必须明白 Vue3 的 ref 和 reactive 问题初中级前端必须掌握的 10 个 Vue 优化技巧分享 15 个 Vue3 全家桶开发的避坑经验 在 Vue.js 中&#xff0c;依赖注入[1]&#xff08;DI&#xff09;是…

中小企业做知识管理如何选择KMS?

编者按&#xff1a;&#xff08;KM&#xff09;是创建、共享、使用和管理组织的知识和信息的过程。它是指通过充分利用知识来实现组织的多学科方法。那么中小企业预算有限的情况下&#xff0c;该如何选择KMS呢 &#xff1f; 关键词&#xff1a;知识管理系统、免安装、免维护 市…

在职读研弥补学历短板——中国人民大学与加拿大女王大学金融硕士项目

在当今社会 “文凭化”的理念下&#xff0c;学历变得很重要。学历会影响到一个人成长发展的各各方面&#xff0c;当我们“工作越久&#xff0c;接触社会越久”&#xff0c;越感觉到学历的重要性。具有高学历&#xff0c;就具有更多的发展机会&#xff0c;具有更多精神上的财富&…

Basler相机一丢包就断开问题解决

问题描述&#xff1a; 两个相机&#xff0c; 一个相机aca2500-14gm连接电脑主板100M网卡没问题&#xff0c;帧率3帧&#xff0c;但是不会断。 一个相机aca2500-14gm连接USB转网口&#xff08;千兆&#xff09;&#xff0c;pylon Viewer采图丢包严重并且几秒后相机断开。 解决…

集合面试题--复杂度分析

为什么要进行复杂度分析&#xff1f; 1指导编写出性能更优的代码2评判别人写的代码的好坏 时间复杂度分析 常见复杂度表示 常见复杂度 空间复杂度

【赠书活动 - 第1期】- 测试工程师Python开发实战(异步图书出品)| 文末送书

⭐️ 赠书 - 测试工程师Python开发实战&#xff08;异步图书出品&#xff09; 当初就是因为开发做不好&#xff0c;才去做测试了…… 这句玩笑话在过去可以说是测试人员的真实写照。 常规测试工作给人的印象&#xff0c;就是弄清楚软件功能&#xff0c;编写测试用例&#xff0…

基于springboot+Redis的前后端分离项目之消息队列(六)-【黑马点评】

&#x1f381;&#x1f381;资源文件分享 链接&#xff1a;https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA?pwdeh11 提取码&#xff1a;eh11 秒杀优化、消息队列 秒杀优化1 秒杀优化-异步秒杀思路2 秒杀优化-Redis完成秒杀资格判断3 秒杀优化-基于阻塞队列实现秒杀优化 Red…

抖音矩阵系统源码开源部署分享(三)

目录 一、 概述&#xff1a; 二、 账号矩阵搭建目的&#xff1a; 三、 抖音矩阵系统源码开发步骤 四、 功能规划 五、 代码开发展示 一、 概述&#xff1a; 抖音矩阵系统是指通过多个账号运营&#xff0c;对账号之间的内容和特征进行细分&#xff0c;账号之间相互引流推广&a…

什么是数字化和数字化转型?终于有人讲明白了!

在我与不同行业、不同岗位甚至不同阶层的人谈论数字化和数字化转型的时候发现一个很有意思的现象&#xff1a; 许多人出于无知或为了自己的利益而开始混淆这两个术语&#xff0c;甚至一些人已经开始将数字化标记为数字化转型&#xff0c;以安抚管理层、获得项目批准或进行销售…

在海外我们该如何推广应用

Google Play和Apple Store上有各种各样不同的应用程序&#xff0c;大量的正面评论和高评级可以成为应用在当前市场上取得成功的关键。大多数用户更喜欢有很多应用评论&#xff0c;积极反馈和高评级的应用程序&#xff0c;因此每条应用程序评论都很重要。确保鼓励用户留下评论&a…

R语言学习——数据框

x c(42,7,64,9) y1:4 z.df data.frame(INDEXy, VALUEx) z.df dim(z.df) # 查看几行几列 colnames(z.df) # 查看列名 rownames(z.df) # 查看行名 z.df[,1] z.df[1,] z.df[c(1,2),c(1,2)]df1 data.frame(C1c(1,5,14,1,54), C2c(9,15,85,9,42), C3c(8,7,42,8,16)) df1 df2 <…