react【三】受控组件/高阶组件/portals/fragment/严格模式/动画

文章目录

  • 1、受控组件
    • 1.1 认识受控组件
    • 1.2 checkout
    • 1.3 selected
    • 1.4 非受控组件
  • 2、高阶组件
    • 2.1 认识高阶组件
    • 2.2 应用1-props增强的基本使用
    • 2.3 对象增强的应用场景-context共享
    • 2.4 应用2-鉴权
    • 2.5 应用3 – 生命周期劫持
    • 2.6、高阶组件的意义
  • 3、Portals
  • 4、fragment
  • 5、StrictMode
  • 6、React过渡动画实现
    • 6.1 CSSTransition
    • 6.2 SwitchTransition
    • 6.3 TransitionGroup

1、受控组件

1.1 认识受控组件

在这里插入图片描述

import React, { PureComponent } from "react";export class App extends PureComponent {constructor() {super();this.state = {userName: "",};}inputChange(e) {const value = e.target.value;this.setState({ userName: value });}submitChange(e) {// 1.阻止表单的默认事件 表单默认会被刷新e.preventDefault();// 2.在这里修改表单数据console.log(e);// 3.发送网络请求}render() {const { userName } = this.state;return (<div><form onSubmit={(e) => this.submitChange(e)}><label htmlFor="userName">用户:<inputid="userName"type="text"name="userName"value={userName}onChange={(e) => this.inputChange(e)}></input></label><button type="submit">注册</button></form></div>);}
}export default App;

在这里插入图片描述

1.2 checkout

在这里插入图片描述

import React, { PureComponent } from "react";export class App extends PureComponent {constructor() {super();this.state = {userName: "",password: "",isAgree: false,hobbies: [{ value: "sing", text: "唱", isChecked: false },{ value: "dance", text: "跳", isChecked: false },{ value: "rap", text: "rap", isChecked: false },],};}handleAgreeChange(e) {this.setState({ isAgree: e.target.checked });}handleHobbiesChange(e, index) {const hobbies = [...this.state.hobbies];hobbies[index].isChecked = e.target.checked;this.setState({ hobbies });}submitChange(e) {// 1.阻止表单的默认事件 表单默认会被刷新e.preventDefault();// 2.在这里修改表单数据console.log(e);const hobbies = this.state.hobbies.filter((item) => item.isChecked);console.log(hobbies);// 3.发送网络请求}render() {const { isAgree, hobbies } = this.state;return (<div><form onSubmit={(e) => this.submitChange(e)}>{/* 单选 */}<label htmlFor="agree"><inputtype="checkbox"id="agree"checked={isAgree}onChange={(e) => this.handleAgreeChange(e)}/>单选</label>{/* 多选 */}<div>{hobbies.map((item, index) => {return (<label htmlFor={item.value} key={index}><inputtype="checkbox"id={item.value}checked={item.isChecked}onChange={(e) => this.handleHobbiesChange(e, index)}/>{item.text}</label>);})}</div><button type="submit">注册</button></form></div>);}
}export default App;

1.3 selected

在这里插入图片描述

import React, { PureComponent } from "react";export class App extends PureComponent {constructor() {super();this.state = {fruit: "orange",fruits: ["orange", "apple"],};}submitChange(e) {// 1.阻止表单的默认事件 表单默认会被刷新e.preventDefault();// 2.在这里修改表单数据console.log(e);// 3.发送网络请求}// 单选fruitChange(e) {console.log(e.target.value);this.setState({ fruit: e.target.value });}//  多选fruitsChange(event) {// event.target.selectedOptions 获取到的不是数组 HTMLCollection [option]// 方法1// const options = Array.from(event.target.selectedOptions);// const values = options.map((item) => item.value);// this.setState({ fruits: values });// 额外补充: Array.from(可迭代对象)// Array.from(arguments,()=>{})// 方法2const values = Array.from(event.target.selectedOptions,(item) => item.value);this.setState({ fruits: values });}render() {const { fruit, fruits } = this.state;return (<div><form onSubmit={(e) => this.submitChange(e)}>{/* select单选 */}<select value={fruit} onChange={(e) => this.fruitChange(e)}><option value="apple">苹果</option><option value="orange">橘子</option><option value="banana">香蕉</option></select>{/* select多选 */}<selectvalue={fruits}multipleonChange={(e) => this.fruitsChange(e)}><option value="apple">苹果</option><option value="orange">橘子</option><option value="banana">香蕉</option></select><button type="submit">注册</button></form></div>);}
}export default App;

1.4 非受控组件

在这里插入图片描述

import React, { PureComponent, createRef } from "react";export class App extends PureComponent {constructor() {super();this.state = { intro: "kiki" };this.introRef = createRef();}submitChange(e) {// 1.阻止表单的默认事件 表单默认会被刷新e.preventDefault();// 2.在这里修改表单数据console.log(e);console.log(this.introRef.current.value);// 3.发送网络请求}render() {const { intro } = this.state;return (<div><form onSubmit={(e) => this.submitChange(e)}><input type="text" defaultValue={intro} ref={this.introRef}></input><button type="submit">注册</button></form></div>);}
}export default App;

2、高阶组件

2.1 认识高阶组件

在这里插入图片描述在这里插入图片描述

import React, { PureComponent } from "react";// 普通类组件
class HelloWorld extends PureComponent {constructor(props) {super(props);}render() {const { name } = this.props;return (<div><span>普通的类组件-{name}</span></div>);}
}// 高阶组件
const Hoc = (Comp) => {class NewCpn extends PureComponent {render() {return (<div><h1>我是高阶组件</h1>{/* 高阶组件传递参数给子组件 */}<Comp name="kiki" /></div>);}}return NewCpn;
};// 调用高阶组件
const HelloWorldHOC = Hoc(HelloWorld);class componentName extends PureComponent {render() {return (<div>{/* 对高阶组件的使用 */}<HelloWorldHOC /></div>);}
}export default componentName;

2.2 应用1-props增强的基本使用

在这里插入图片描述

  • enhanced_props.js
import React, { PureComponent } from "react";const enhancedUserInfo = (OriginComponent) => {class NewComponent extends PureComponent {constructor(props) {super(props);this.state = {userInfo: {name: "kiki",age: "18",},};}render() {// 1.将state.userInfo的内容全部传递给子组件// 2.将OriginComponents 原本的props也给注入return <OriginComponent {...this.props} {...this.state.userInfo} />;}}return NewComponent;
};export default enhancedUserInfo;
  • about.jsx
import React, { PureComponent } from 'react'
import enhancedUserInfo from '../hoc/enhanced_props'export class About extends PureComponent {render() {return (<div>About: {this.props.name}</div>)}
}export default enhancedUserInfo(About)
  • App.jsx
import React, { PureComponent } from "react";
import enhancedUserInfo from "./hoc/enhanced_props";
import About from "./pages/About";const Home = enhancedUserInfo((props) => {// 通过enhancedUserInfo 将它本身的state传递给该函数组件return (<h1>{props.name}-{props.age}</h1>);
});const HelloWord = enhancedUserInfo((props) => {return (<h1>{/* 调用组件的时候传递的参数也可以拿到 */}{props.name}-{props.age}-{props.banner}</h1>);
});export class App extends PureComponent {render() {return (<div><Home />{/* 给高阶函数传递props */}<HelloWord banner="['a','b']" />{/* 调用已经注入enhancedUserInfo的组件 */}<About /></div>);}
}export default App;

2.3 对象增强的应用场景-context共享

  • 使用高阶组件来跨组件传参
    在这里插入图片描述

  • theme_context.js (创建context)

import { createContext } from "react";const themeContext = createContext();export default themeContext;
  • with_theme.js(props增强
import ThemeContext from "../context/theme_context";const withTheme = (OriginComp) => {return (props) => {return (// 将共享context传递给子组件 把传递给高阶函数的props也传递给子组件<ThemeContext.Consumer>{(value) => {return <OriginComp {...value} {...props} />;}}</ThemeContext.Consumer>);};
};export default withTheme;
  • procuct组件
import React, { PureComponent } from "react";
import ThemeContext from "../context/theme_context";
import withTheme from "../hoc/with_theme";// export class Product extends PureComponent {
//   render() {
//     return (
//       <div>
//         Product:
//         <ThemeContext.Consumer>
//           {
//             value => {
//               return <h2>theme:{value.color}-{value.size}</h2>
//             }
//           }
//         </ThemeContext.Consumer>
//       </div>
//     )
//   }
// }// export default Productexport class Product extends PureComponent {render() {const { color, size, name } = this.props;return (<div><h2>context注入的参数: {color}-{size}</h2><div>传递给product的参数:{name}</div></div>);}
}// 将context的参数注入给product
export default withTheme(Product);
  • App.jsx
import React, { PureComponent } from "react";
import ThemeContext from "./context/theme_context";
import Product from "./pages/Product";export class App extends PureComponent {render() {return (<div><ThemeContext.Provider value={{ color: "red", size: 30 }}><Product name="kiki" /></ThemeContext.Provider></div>);}
}export default App;

2.4 应用2-鉴权

在这里插入图片描述

  • login_auth
const loginAuth = (OriginComp) => {return (props) => {const token = localStorage.getItem("token");return token ? <OriginComp {...props} /> : "请先登录";};
};export default loginAuth;
  • card.jsx
import React, { PureComponent } from 'react'
import loginAuth from '../hoc/login_auth'export class Cart extends PureComponent {render() {return (<h2>Cart Page</h2>)}
}export default loginAuth(Cart)
  • app.jsx
import React, { PureComponent } from "react";
import Cart from "./pages/Cart";export class App extends PureComponent {handleClick() {localStorage.setItem("token", "kiki");// 修改本地缓存并不会发生界面刷新 所以需要强制刷新// 强制刷新在一般情况下部推荐 so 请使用 statethis.forceUpdate();}render() {return (<div><button onClick={(e) => this.handleClick()}>点击登录</button><Cart /></div>);}
}export default App;

2.5 应用3 – 生命周期劫持

  • log_render_time
import { PureComponent } from "react";function logRenderTime(OriginComponent) {return class extends PureComponent {UNSAFE_componentWillMount() {this.beginTime = new Date().getTime()}componentDidMount() {this.endTime = new Date().getTime()const interval = this.endTime - this.beginTimeconsole.log(`当前${OriginComponent.name}页面花费了${interval}ms渲染完成!`)}render() {return <OriginComponent {...this.props}/>}}
}export default logRenderTime
  • detail.jsx
import React, { PureComponent } from 'react'
import logRenderTime from '../hoc/log_render_time'export class Detail extends PureComponent {// UNSAFE_componentWillMount() {//   this.beginTime = new Date().getTime()// }// componentDidMount() {//   this.endTime = new Date().getTime()//   const interval = this.endTime - this.beginTime//   console.log(`当前页面花费了${interval}ms渲染完成!`)// }render() {return (<div><h2>Detail Page</h2><ul><li>数据列表1</li><li>数据列表2</li><li>数据列表3</li><li>数据列表4</li><li>数据列表5</li><li>数据列表6</li><li>数据列表7</li><li>数据列表8</li><li>数据列表9</li><li>数据列表10</li></ul></div>)}
}export default logRenderTime(Detail)
  • App.jsx
import React, { PureComponent } from 'react'
import Detail from './pages/Detail'export class App extends PureComponent {render() {return (<div><Detail/></div>)}
}export default App

2.6、高阶组件的意义

在这里插入图片描述

3、Portals

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、fragment

在这里插入图片描述

import React, { PureComponent, Fragment } from 'react'export class App extends PureComponent {constructor() {super() this.state = {sections: [{ title: "哈哈哈", content: "我是内容, 哈哈哈" },{ title: "呵呵呵", content: "我是内容, 呵呵呵" },{ title: "嘿嘿嘿", content: "我是内容, 嘿嘿嘿" },{ title: "嘻嘻嘻", content: "我是内容, 嘻嘻嘻" },]}}render() {const { sections } = this.statereturn (<><h2>我是App的标题</h2><p>我是App的内容, 哈哈哈哈</p><hr />{sections.map(item => {return (<Fragment key={item.title}><h2>{item.title}</h2><p>{item.content}</p></Fragment>)})}</>)}
}export default App

5、StrictMode

在这里插入图片描述
在这里插入图片描述

6、React过渡动画实现

在这里插入图片描述
在这里插入图片描述

6.1 CSSTransition

在这里插入图片描述
在这里插入图片描述

  • npm install react-transition-group --save
    在这里插入图片描述
import React, { createRef, PureComponent } from "react";
import { CSSTransition } from "react-transition-group";
import "./style.css";export class App extends PureComponent {constructor(props) {super(props);this.state = {isShow: true,};// 在严格模式下会报错 所以需要绑定refthis.sectionRef = createRef();}render() {const { isShow } = this.state;return (<div><button onClick={(e) => this.setState({ isShow: !isShow })}>切换</button>{/* { isShow && <h2>哈哈哈</h2> } */}{/* timeout是必须要设置的,他是控制类的移出事件 动画时间还是由CSS控制 */}{/* unmountOnExit:用来决定是否移除组件 */}{/* appear:刚挂载的时候是否有动画 */}<CSSTransitionnodeRef={this.sectionRef}in={isShow}unmountOnExit={true}classNames="why"timeout={2000}appearonEnter={(e) => console.log("开始进入动画")}onEntering={(e) => console.log("执行进入动画")}onEntered={(e) => console.log("执行进入结束")}onExit={(e) => console.log("开始离开动画")}onExiting={(e) => console.log("执行离开动画")}onExited={(e) => console.log("执行离开结束")}><div className="section" ref={this.sectionRef}><h2>哈哈哈</h2><p>我是内容, 哈哈哈</p></div></CSSTransition></div>);}
}export default App;

6.2 SwitchTransition

在这里插入图片描述
在这里插入图片描述

  • App.jsx
import React, { PureComponent } from "react";
import { SwitchTransition, CSSTransition } from "react-transition-group";
import "./style.css";export class App extends PureComponent {constructor() {super();this.state = {isLogin: true,};}render() {const { isLogin } = this.state;return (<div><SwitchTransition mode="out-in"><CSSTransition// 在切换组件的时候用的是key 显示和隐藏key={isLogin ? "exit" : "login"}classNames="login"timeout={1000}><button onClick={(e) => this.setState({ isLogin: !isLogin })}>{isLogin ? "退出" : "登录"}</button></CSSTransition></SwitchTransition></div>);}
}export default App;

6.3 TransitionGroup

在这里插入图片描述
在这里插入图片描述

import React, { PureComponent } from "react";
import { TransitionGroup, CSSTransition } from "react-transition-group";
import "./style.css";export class App extends PureComponent {constructor() {super();this.state = {books: [{ id: 111, name: "你不知道JS", price: 99 },{ id: 222, name: "JS高级程序设计", price: 88 },{ id: 333, name: "Vuejs高级设计", price: 77 },],};}addNewBook() {const books = [...this.state.books];books.push({id: new Date().getTime(),name: "React高级程序设计",price: 99,});this.setState({ books });}removeBook(index) {const books = [...this.state.books];books.splice(index, 1);this.setState({ books });}render() {const { books } = this.state;return (<div><h2>书籍列表:</h2><TransitionGroup component="ul">{books.map((item, index) => {return (// 这里不用index作为key是因为在删除的时候Index是动态变化的会发生错乱<CSSTransition key={item.id} classNames="book" timeout={1000}><li><span>{item.name}-{item.price}</span><button onClick={(e) => this.removeBook(index)}>删除</button></li></CSSTransition>);})}</TransitionGroup><button onClick={(e) => this.addNewBook()}>添加新书籍</button></div>);}
}export default App;

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

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

相关文章

17.3.1.6 自定义处理

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 模拟某款图像处理软件的处理&#xff0c;它只留下红色、绿色或者蓝色这样的单一颜色。 首先按照颜色划分了6个色系&#xff0c;分别…

disql备份还原

disql备份还原 前言 本文档根据官方文档&#xff0c;进行整理。 一、概述 在 disql 工具中使用 BACKUP 语句你可以备份整个数据库。通常情况下&#xff0c;在数据库实例配置归档后输入以下语句即可备份数据库&#xff1a; BACKUP DATABASE BACKUPSET db_bak_01;语句执行完…

java生态环境评价Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 生态环境评价管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysq…

.netcore音乐播放器 musicPlayer

html音乐播放器 .net core mvc 音乐播放器 支持上传本地音乐到云端 支持通过文件夹创建歌单(不需要数据库和其他数据存储) 通过歌单分类 播放歌曲 支持播放暂停 上一首 下一首切换 支持显示歌曲列表 歌单切换 展示歌曲根据歌单名去获取歌曲显示 功能 版权原因 或者想创建自己的…

macOS 安装 conda

macOS 安装 conda 安装 conda参考 Conda是一个开源的软件包管理系统和环境管理系统&#xff0c;用于安装和管理软件包和其依赖项。 安装 conda mkdir miniconda3 cd miniconda3 bash Miniconda3-latest-MacOSX-x86_64.sh$ conda list参考 macOS 安装 conda开始使用conda

python+django学习交流论坛系统244t6

系统可以提供信息显示和相应服务&#xff0c;其管理员管理用户发布的博客文章以及用户之间的论坛交流信息&#xff0c;管理留言以及文章分类信息。用户在论坛交流模块发布帖子以及评论帖子&#xff0c;在前台查看和评论其他用户发布的博客文章&#xff0c;收藏博客文章&#xf…

esp8266-01s WIFI模块使用(一)- AT指令

时间记录&#xff1a;2024/2/15 一、注意事项 &#xff08;1&#xff09;使用英文双引号表示字符串数据 &#xff08;2&#xff09;默认波特率115200 &#xff08;3&#xff09;AT指令以“\r\n”结尾 &#xff08;4&#xff09;3.3V电源接口先连接单片机的3.3V&#xff0c;如…

阿里云“BGP(多线)”和“BGP(多线)_精品”区别价格对比

阿里云香港等地域服务器的网络线路类型可以选择BGP&#xff08;多线&#xff09;和 BGP&#xff08;多线&#xff09;精品&#xff0c;普通的BGP多线和精品有什么区别&#xff1f;BGP&#xff08;多线&#xff09;适用于香港本地、香港和海外之间的互联网访问。使用BGP&#xf…

用HTML5 Canvas创造视觉盛宴——动态彩色线条效果

目录 一、程序代码 二、代码原理 三、运行效果 一、程序代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- 声明文档类型为XHTML 1.0 Transitional -…

ElasticSearch之search API

写在前面 本文看下查询相关内容&#xff0c;这也是我们在实际工作中接触的最多的&#xff0c;所以有必要好好学习下&#xff01; 1&#xff1a;查询的分类 主要分为如下2类&#xff1a; 1:基于get查询参数的URI search 2&#xff1a;基于post body的request body search&am…

Netty Review - 直接内存的应用及源码分析

文章目录 Pre概述应用访问效率&#xff1a; 堆内存 VS 直接内存申请效率&#xff1a; 堆内存 VS 直接内存数据存储结构&#xff1a; 堆内存 VS 直接内存结论 ByteBuffer.allocateDirect 源码分析unsafe.allocateMemory(size) ---> C方法 JVM参数 -XX:MaxDirectMemorySize直接…

隐函数的求导【高数笔记】

1. 什么是隐函数&#xff1f; 2. 隐函数的做题步骤&#xff1f; 3. 隐函数中的复合函数求解法&#xff0c;与求导中复合函数求解法有什么不同&#xff1f; 4. 隐函数求导的过程中需要注意什么&#xff1f;

Mysql运维篇(四) Xtarbackup--备份与恢复练习

一路走来&#xff0c;所有遇到的人&#xff0c;帮助过我的、伤害过我的都是朋友&#xff0c;没有一个是敌人。如有侵权&#xff0c;请留言&#xff0c;我及时删除&#xff01; 前言 xtrabackup是Percona公司CTO Vadim参与开发的一款基于InnoDB的在线热备工具&#xff0c;具有…

164基于matlab的奇异值分解、小波降噪、zoom细化

基于matlab的奇异值分解、小波降噪、zoom细化。程序已调通&#xff0c;可直接运行。 164 奇异值分解 小波降噪 zoom细化 (xiaohongshu.com)

Spring AMQP(3.1.1)设置ConfirmCallback和ReturnsCallback

文章目录 一、起因二、代码1. 定义exchange和queue2. RabbitTemplate3. EnhancedCorrelationData4. 发送消息 环境如下 VersionSpringBoot3.2.1spring-amqp3.1.1RabbitMq3-management 一、起因 老版本的spring-amqp在CorrelationData上设置ConfirmCallback。但是今天却突然发…

Python访问数据库

目录 SQLite数据库 SQLite数据类型 Python数据类型与SQLite数据类型的映射 使用GUI管理工具管理SQLite数据库 数据库编程的基本操作过程 sqlite3模块API 数据库连接对象Connection 游标对象Cursor 数据库的CRUD操作示例 示例中的数据表 无条件查询 有条件查询 插入…

【Java多线程】对进程与线程的理解

目录 1、进程/任务&#xff08;Process/Task&#xff09; 2、进程控制块抽象(PCB Process Control Block) 2.1、PCB重要属性 2.2、PCB中支持进程调度的一些属性 3、 内存分配 —— 内存管理&#xff08;Memory Manage&#xff09; 4、线程&#xff08;Thread&#xff09;…

Unity(单元测试)在STM32上的移植与应用

概述 Unity Test是一个为C构建的单元测试框架。本文基于STM32F407为基础&#xff0c;完全使用STM32CubeIDE进行开发&#xff0c;移植和简单使用Unity。 单片机型号&#xff1a;STM32F407VET6 软件&#xff1a;STM32CubeIDE Version: 1.14.1 Unity Version&#xff1a;2.…

相机图像质量研究(22)常见问题总结:CMOS期间对成像的影响--光学串扰

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

LeetCode、338. 比特位计数【简单,位运算】

文章目录 前言LeetCode、338. 比特位计数【中等&#xff0c;位运算】题目链接与分类思路位运算移位处理前缀思想实现 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java…