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.mzph.cn/news/685524.shtml

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

相关文章

交大论文下载器

原作者地址&#xff1a; https://github.com/olixu/SJTU_Thesis_Crawler 问题&#xff1a; http://thesis.lib.sjtu.edu.cn/的学位论文下载系统&#xff0c;该版权保护系统用起来很不方便&#xff0c;加载起来非常慢&#xff0c;所以该下载器实现将网页上的每一页的图片合并…

GPU独显下ubuntu屏幕亮度不能调节解决方法

GPU独显下屏幕亮度不能调节&#xff08;假设你已经安装了合适的nvidia显卡驱动&#xff09;&#xff0c;我试过修改 /etc/default/grub 的 GRUB_CMDLINE_LINUX_DEFAULT"quiet splash acpi_backlightvendor" &#xff0c;没用。修改和xorg.conf相关的文件&#xff0c;…

不花一分钱,在 Mac 上跑 Windows(M1/M2 版)

这是在 MacOS M1 上体验最新 Windows11 的效果&#xff1a; VMware Fusion&#xff0c;可以运行 Windows、Linux 系统&#xff0c;个人使用 licence 免费 安装流程见 &#x1f449; https://zhuanlan.zhihu.com/p/452412091 从申请 Fusion licence 到下载镜像&#xff0c;再到…

安装 Windows Server 2019

1.镜像安装 镜像安装:Windows Server 2019 2.安装过程(直接以图的形式呈现) 先选择""我没有产品密钥"",选择桌面体验 选择自定义 设置密码后继续 安装成功

07-k8s中secret资源02-玩转secret

一、回顾secret资源的简单实用 第一步&#xff1a;将想要的数据信息【key&#xff1a;value】中的value值&#xff0c;使用base64编码后&#xff0c;写入secret资源清单中&#xff1b; 第二步&#xff1a;创建secret资源&#xff1b; 第三步&#xff1a;pod资源引用secret资源&…

第2讲springsecurity+vue通用权限系统

阿里云 maven阿里云镜像 <?xml version"1.0" encoding"UTF-8"?><!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for addition…

C++,stl,常用排序算法,常用拷贝和替换算法

目录 1.常用排序算法 sort random_shuffle merge reverse 2.常用拷贝和替换算法 copy replace replace_if swap 1.常用排序算法 sort 默认从小到大排序 #include<bits/stdc.h> using namespace std;int main() {vector<int> v;v.push_back(1);v.push_ba…

【友塔笔试面试复盘】八边形取反问题

问题&#xff1a;一个八边形每条边都是0&#xff0c;现在有取反操作&#xff0c;选择一条边取反会同时把当前边和2个邻边取反&#xff08;如果是0变为1&#xff0c;如果是1变为0&#xff09; 现在问你怎么取反能使得八条边都变为1. 当时陷入了暴力递归漩涡&#xff0c;给出一个…

问题:内存时序参数 CASLatency 是() #学习方法#微信#微信

问题&#xff1a;内存时序参数 CASLatency 是&#xff08;&#xff09; A&#xff0e;行地址控制器延迟时间 B&#xff0e;列地址至行地址延迟时间 C&#xff0e;列地址控制器预充电时间 D&#xff0e;列动态时间 参考答案如图所示

[职场] 求职如何设置预期 #笔记#经验分享

求职如何设置预期 在求职的道路上&#xff0c;无论处于哪个年龄阶段&#xff0c;合理的就业期望值才能使我们的愿望与社会的需求相吻合&#xff0c;才能让自己在今后的工作中发挥出最大的实力与能力。 一、结合测评软件&#xff0c;明确求职目标 根据霍兰德职业兴趣测试结果&a…

题目:3.神奇的数组(蓝桥OJ 3000)

问题描述&#xff1a; 解题思路&#xff1a; 官方&#xff1a; 我的总结&#xff1a; 利用双指针遍历每个区间并判断是否符合条件&#xff1a;若一个区间符合条件则该区间在其左端点不变的情况下的每一个子区间都符合条件&#xff0c;相反若一个区间内左端点固定情况下有一个以…

javax.servlet 和 jakarta.servlet的关系和使用tomcat部署 jakarta.servlet

1&#xff0c;javax.servlet 和 jakarta.servlet的关系 javax.servlet 和 jakarta.servlet 是 Java Servlet API 的两个版本。 Java Servlet API 是由 Sun Microsystems&#xff08;现在是 Oracle&#xff09;开发和维护的&#xff0c;其包名以 javax.servlet 开头。从 Java …

mysql数据库 mvcc

在看MVCC之前我们先补充些基础内容&#xff0c;首先来看下事务的ACID和数据的总体运行流程 数据库整体的使用流程: ACID流程图 mysql核心日志: 在MySQL数据库中有三个非常重要的日志binlog,undolog,redolog. mvcc概念介绍&#xff1a; MVCC&#xff08;Multi-Version Concurr…

17.3.1.3 灰度

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 灰度的算法主要有以下三种&#xff1a; 1、最大值法: 原图像&#xff1a;颜色值color&#xff08;R&#xff0c;G&#xff0c;B&a…

react+ts【项目实战一】配置项目/路由/redux

文章目录 1、项目搭建1、创建项目1.2 配置项目1.2.1 更换icon1.2.2 更换项目名称1.2.1 配置项目别名 1.3 代码规范1.3.1 集成editorconfig配置1.3.2 使用prettier工具 1.4 项目结构1.5 对css进行重置1.6 注入router1.7 定义TS组件的规范1.8 创建代码片段1.9 二级路由和懒加载1.…

c入门第十八篇——支持学生数的动态增长(链表,指针的典型应用)

数组最大的问题&#xff0c;就是不支持动态的扩缩容&#xff0c;它是静态内存分配的&#xff0c;一旦分配完成&#xff0c;其容量是固定的。为了支持学生的动态增长&#xff0c;这里可以引入链表。 链表 在C语言中&#xff0c;链表是一种常用的数据结构&#xff0c;它由一系列…

STM32 寄存器操作 GPIO 与下降沿中断

一、如何使用stm32寄存器点灯&#xff1f; 1.1 寄存器映射表 寄存器本质就是一个开关&#xff0c;当我们把芯片寄存器配置指定的状态时即可使用芯片的硬件能力。 寄存器映射表则是开关的地址说明。对于我们希望点亮 GPIO_B 的一个灯来说&#xff0c;需要关注以下的两个寄存器…

Ps:创建调色观察图层组

人们往往受图像内容、所用显示器、自身对色彩敏感程度等的影响&#xff0c;无法准确地把握一张照片的明暗关系或色彩关系&#xff0c;因此导致修图时无方向、不精准。 如果通过数字化的方式建立观察图层&#xff08;组&#xff09;来辅助我们客观地分析照片&#xff0c;从而可以…

ARM编译器5.06下载安装

ARM编译器5.06下载安装 1.官网下载 进入官方网站ARM Complier v5.06官网下载页面 进入后的界面为 往下翻&#xff0c;找到如图位置的5.06 for windows的文件&#xff0c;点击下载&#xff0c;下载时需要登录账号 2.安装 先解压下载的压缩文件&#xff0c;在installer文件夹里…

解线性方程组(一)——克拉默法则求解(C++)

克拉默法则 解线性方程组最基础的方法就是使用克拉默法则&#xff0c;需要注意的是&#xff0c;该方程组必须是线性方程组。 假设有方程组如下&#xff1a; { a 11 x 1 a 12 x 2 ⋯ a 1 n x n b 1 a 21 x 1 a 22 x 2 ⋯ a 2 n x n b 2 ⋯ ⋯ ⋯ a n 1 x 1 a n 2 x 2…