react—Hook(2)

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.hqwc.cn/news/8975.html

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

相关文章

HTML 编辑器的介绍及推荐

HTML 编辑器 HTML 编辑器是用于编写 HTML 的工具&#xff0c;使用 HTML 编辑器时以编辑主题&#xff0c;索引&#xff0c;自定义窗口&#xff0c;选择添加搜索页。 使用 Notepad 或 TextEdit 来编写 HTML 下列是三种专门用于编辑 HTML 的 HTML 编辑器&#xff1a; Adobe Dream…

使用SDWAN构建安全的混合WAN

使用SD-WAN构建安全的混合WAN SDWAN的爆炸已成为头条新闻了一年多。企业正在以惊人的速度采取SDWAN&#xff0c;不但可以为分支机构提供更灵活的连接和利用程序性能&#xff0c;而且可以跨全部网络提供。远程“超级用户”依托SDWAN(通过将小型台式机装备提供的安全性&#xff…

【go】数据表转csv

文章目录 1 基本结构1.1 数据1.2 数据结构 2 代码3 tip 1 基本结构 1.1 数据 1.2 数据结构 2 代码 代码&#xff1a; package mainimport ("database/sql""encoding/csv""fmt"_ "github.com/go-sql-driver/mysql""log"&q…

大数据面试题:Kafka的Message包括哪些信息

面试题来源&#xff1a; 《大数据面试题 V4.0》 大数据面试题V3.0&#xff0c;523道题&#xff0c;679页&#xff0c;46w字 参考答案&#xff1a; 一个 Kafka 的 Message 由一个固定长度的 header 和一个变长的消息体 body 组成&#xff0c;header 部分由一个字节的 magic&…

进阶课程1:jvm内存模型

目录 JVM内存结构转换总结一下 JVM整体结构线程栈 JVM栈内存结构栈帧操作数栈局部变量表 JVM堆内存结构堆内存非堆内存 JMM内容&#xff1a;讲解JMM的三大特性1.原子性2.可见性3.有序性 视频 JVM内存结构 JVM内部由线程栈和堆内存组成。 简单描述就是我们的原生类型的局部变量…

Hive基础知识

1.Hive简介 Hive是由Facebook开源用于解决海量结构化日志的数据统计工具。Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张表&#xff0c;并提供类SQL查询功能。 2.Hive本质 Hive的本质是将HQL转化成MapReduce程序。 Hive处理的数据存储在H…

基于线性准则的考虑风力发电不确定性的分布鲁棒优化机组组合(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Centos7部署项目

Centos7部署项目 Centos7部署项目Centos7安装gitCentos7从github拉取代码配置git配置用于提交代码的用户名配置用户邮箱生成公钥效果如下 github添加SSH key打开你的GitHub获取ssh key公钥内容验证 拉取项目新建空白文件夹拉取项目 使用Docker Compose创建项目容器创建docker-c…

基于minsit数据集的图像分类任务|CNN简单应用项目

Github地址 Image-classification-task-based-on-minsit-datasethttps://github.com/Yufccode/CollegeWorks/tree/main/ImageProcessing/Image-classification-task-based-on-minsit-dataset README 摘要 本次实验报告用两种方式完成了基于minst数据集完成了图像的分类任务…

深度解读AIGC存储解决方案

5月26日&#xff0c;2023数据基础设施技术峰会在苏州举办&#xff0c;腾讯云首席存储技术专家温涛受邀出席并分享了腾讯云领先的存储技术在AIGC场景中的应用&#xff0c;通过对AIGC业务流程和场景的提炼&#xff0c;从内容生成、内容审核和内容智理三要素介绍了如何智能的存储和…

RabbitMQ之发布确认

RabbitMQ发布确认 1 发布确认原理2 发布确认的策略2.1 开启发布确认的方法2.2 单个确认发布 2.3 批量确认发布2.4 异步确认发布2.5 如何处理异步未确认消息2.6 以上3种确认速度对比 1 发布确认原理 生产者将信道设置为 confirm 模式&#xff0c;一旦信道进入 confirm 模式&…

2021 RoboCom 世界机器人开发者大赛-高职组(初赛)

编程题得分&#xff1a;100 总分&#xff1a;100 目录 7-1 机器人打招呼 (5分) 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 7-2 人脸识别 (10分) 输入格式&#xff1a; 输出格式&#xff1a; 输入样例 1&#xff1a; 输…