React入门笔记(二)

2023-11-09

React入门笔记(二)

1.前情回顾

    书接上回,React入门笔记(一)——主要介绍React的基本特点,虚拟dom的实现原理,利用包管理工具搭建基本的React单页面引用等。如果你跳过了前面的项目配置也没关系,这里再来贴一张前面的代码结构(下面的介绍中会使用到):
在这里插入图片描述

2.组件

    相信在前面的学习中,你可以深入的体会到React与Vue在使用上的相同之处吧。对我们来说确实是一件好事。前面提到React同样支持组件化开发,组件化开发能够很好的提高代码的复用性,管理起来也更加方便。在React中组件分为函数型组件和类组件(其实就是写法有些差异,本质相同)。
(1)函数型组件,举例如下:

//组件编写(本质上使用的是JSX语法糖)
function clickFunction() {
  alert('这简直一模一样!');
}
const App = () => (
  <div
    id='myApp'
    className='zhangsan'
    style={{
      color: 'red',
      backgroundColor: 'pink',
      height: '300px',
      width: '400px',
      display: 'flex',
      justifyItems: 'center',
      alignItems: 'center',
    }}
    onClick={clickFunction}
  >
    <div style={{ width: '100%', textAlign: 'center' }}>这是一个React项目!</div>
  </div>
);
export default App;

组件的使用如下:

//src/index.js入口文件
import reactDom from 'react-dom/client';
import App from './App';
const root = reactDom.createRoot(document.getElementById('root'));
root.render(<App />);

(2)类组件,使用如下:

import React from 'react';
//注意需要继承React.Component并实现里面的render方法
class ClassApp extends React.Component {
  clickFun() {
    alert('这个是类组件');
  }
  render() {
    return (
      <div
        id='myApp'
        className='lisi'
        style={{
          color: 'blue',
          backgroundColor: 'pink',
          height: '300px',
          width: '400px',
          display: 'flex',
          justifyItems: 'center',
          alignItems: 'center',
        }}
        onClick={this.clickFun}
      >
        <div style={{ width: '100%', textAlign: 'center' }}>我是一个类组件</div>
      </div>
    );
  }
}
export default ClassApp;

    Java看到了露出了诡异的笑容,由于我这里使用了click函数,这里报了个警告:[Violation] 'click' handler took 1081ms,本质是因为点击时间触发了js事件阻塞,被开发环境的依赖截获到了。
    当然组件光有这些显然不是很够,和Vue一样组件肯定得有传参和父子组件传值,不然这些基本功能都无法实现,组件使用就显得很尴尬。下面还是以函数组件为主来介绍propsstate,毕竟在JavaScript里面函数写法还是更常见一些。给出使用举例:

//src/index.js入口文件
import reactDom from 'react-dom/client';
import Card from './Components/Card/Card.js';
const root = reactDom.createRoot(document.getElementById('root'));
const cardList = [
  {
    img: 'https://create.nightowl.top/static/tabbar/index-active.png',
    desc: '这里是首页描述内容',
  },
  {
    img: 'https://nightowl.top/static/images/icons/room.png',
    desc: '这里是虚拟试衣间描述',
  },
  {
    img: 'https://nightowl.top/static/images/icons/communicate.png',
    desc: '这里是消息功能描述内容',
  },
];
root.render(
  cardList.map((item) => <Card desc={item.desc} imgSrc={item.img} />)
);

具体组件的编写以及效果展示如下:
在这里插入图片描述
说明如下几点:
(1)对于函数组件,props将作为参数传入,获取的就是使用组件实例的时候在组件上面挂载的属性,注意props属性都是可读属性,都不够中途修改;
(2)组件如果是一个序列的话,需要添加key值,用作组件变化的标识(性能优化的一种手段,方便检测组件是否需要重新渲染),建议使用后端传过来的唯一值,如果单纯使用索引的话,可能会由于之后组件顺序改变,可能需要重新渲染大量的组件,顺序改变相当于大量的属性的key都发生了变化;
(3)在组件的属性中可以和Vue一样在{}直接写函数代码,例如: desc={item.desc.toUpperCase()}
(4)往组件上挂载函数,错误写法如下:

import './Card.css';
const Card = (props) => {
  function testFun() {
    props.desc = String(props.desc).toLowerCase();
    console.log('这里是测试函数,测试将描述转回小写!', props.desc);
  }
  return (
    <div className='card-box' onClick={testFun}>
      <div className='card-img'>
        <img src={props.imgSrc} alt='来源——易搭衣橱' />
      </div>
      <div className='card-content'>{props.desc}</div>
    </div>
  );
};
export default Card;

原因这里的props为只读函数:
在这里插入图片描述
    那肯定不能缺少组件的基本功能,于是就有了state,这个和Vue里面有些相似,能够实现对于组件修改和重新渲染,使用方法如下:
在这里插入图片描述
可以发现state的使用首先需要从react里面解构出UseSate方法,然后利用UseState来创建一个State类型变量(本质是一个方法和数组),初始传入的参数为state初始值,后一个参数是重新修改state的方法:

  let state = useState(1);
  let count = state[0];//获取数组里面的数据
  let setCount = state[1];//获取state数组里面的操作函数
  function testFun() {
    console.log('点击事件被触发!');
    setCount(count + 100);//被调用后能够触发页面渲染
  }

这个写法显然不是很优雅,可以使用如下写法:

  let [count, setCount] = useState(1);
  function testFun() {
    console.log('点击事件被触发!');
    setCount(count + 100);
  }

接下来探讨一下State的使用注意点。如果是被操作的是一个对象,你可能想到的方法如下:
在这里插入图片描述
分析原因:发生了对象的直接替换,新的对象里面没有age属性,解决方法浅拷贝:
在这里插入图片描述
其他的浅复制就不再举例了,如果两次的对象完全一致(无论是深拷贝还是浅拷贝)那么将不会触发修改,也就是不会重新渲染UI。使用拷贝,代码看起来还是不是很舒服,于是有了如下的语法糖写法:

 setCount({ ...userInfo, username: '李四' });

下面需要明确一点,setState是异步的:

 let [count, setCount] = useState(1);
  function testFun() {
    setTimeout(() => {
      console.log('函数被触发');
      setCount(count + 100);
    }, 1000);
  }

在这里插入图片描述
    这里右边的实际函数进入了8次,但是只增加了2次,是因为State函数调用是异步的,导致一些函数的修改被react自动合并了,目的是提高性能。是不是有点像自动给你加了个防抖,但是有些时候可能你需要每次点击都完整执行,也就是不想“防抖”了,那么可以使用回调函数来解决这个问题:

 function testFun() {
    setTimeout(() => {
      console.log('函数被触发');
      setCount((preCounter) => preCounter + 100);
    }, 1000);
  }

    说明:setCount()方法实际有两种参数,一种是直接传入数值,数值将会替代state的前一个值,但是存在更改合并机制提高性能;另一种是函数参数,在这个函数内部,函数自己的形参能够精准的获取到上一次渲染之后的值,如果想要更详细的理解State,可以查看这篇文章:react setState核心实现原理。里面提到,setState的一段时间合并是根据JS的事件队列实现的,一次事件循环调用进行一次setState的合并和组件渲染。事件循环其实不难理解,可以想想那个经典的打印输出面试题
    接下来聊聊ref(Vue中其实也有这个),ref能够获取实际的dom对象。有些时候可能不仅仅需要获取虚拟的dom,还需要直接获取实际(原生)的dom对象。获取实际dom对象需要使用useRef的钩子函数,useRef钩子函数只能够在函数组件或者自定义钩子函数里面写,创建之后会返回一个普通的js对象,使用举例如下:
在这里插入图片描述
    ref对象同样能够修改dom对象,使用方法如下:

 function testFun() {
    console.log('输出ref对象:', testRef);
    testRef.current.innerHTML =
      '这是点击事件触发之后通过Ref对象修改之后的效果。';
  }

在这里插入图片描述
    但是并不建议这么写,因为这样其实和react底层冲突了,相当于React想要去重新渲染,你却依然把被渲染的对象给找了回来。也可以看到在Vue里面还是很少直接操作真实dom的。
    如果你想说,你可能更喜欢Java那种面向对象的写法,当然也是可以的,虽然不能使用ref但是state是完全可以满足的,类组件的state使用如下:

import './ClassCard.css';
import React from 'react';
class Card extends React.Component {
  state = {
    username: '张三',
    age: '18',
  };
  testFun = () => {
    console.log('点击事件被触发!');
    this.setState({ username: '凌空暗羽' });
  };
  render() {
    return (
      <div className='card-box' onClick={this.testFun}>
        <div className='card-img'>
          <img src={this.props.imgSrc} alt='来源——易搭衣橱' />
        </div>
        <div className='card-content'>
          {this.state.username}-{this.state.age}
        </div>
      </div>
    );
  }
}
export default Card;

说明如下几点:
(1)propsstate的使用和前面的函数组件非常类似,其实就是把这些propsstate全部挂载到了实例中了。state里面不需要使用useState方法构建,state已经相当于函数组件里面的继承成员了,直接用就完事,在修改的时候需要使用this.setState来修改,有微信小程序开发那味儿了;
(2)setState函数在类组件中只会修改state中已经存在的属性,其他的属性依然自动保留,也就是不需要像函数组件那样还需要浅复制一下。当然还需要注意这个只支持state的一级保留,并不支持state里面的二级属性,所以二级及以下还是得使用语法糖浅拷贝;
(3)注意setState前面的this需要注意,需要写成箭头函数的形式,这个其实就是this的作用域问题,属于基础基础知识,不太清楚的友友们可以去搜一搜。
    最后,函数组件和类组件各有优点,本质上实现的功能差不多,除了函数组件多支持了一个对性能不是很友好的ref对象外,函数组件代码更加简洁,但是结构显得没有类模式那么清晰,觉得那个适合自己用哪个就行。

3.视频教程地址

    参考视频教程:尚硅谷李立超——React

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React入门笔记(二) 的相关文章

  • pubnub 和 head.js

    有没有人成功整合过pubnub http www pubnub com 和 head js 正确吗 Pubnub http www pubnub com 希望我将他们的脚本放在页面底部并带有 div 就在它前面的标签 这可以确保在最后调用
  • Jasmine-jQuery loadFixtures 未定义

    我对整个茉莉花的事情仍然很陌生 在过去的几个小时里我陷入了这个问题 我尝试使用 loadFixture 加载外部夹具文件 我使用 Jasmine 2 0 0 和 Jasmine jQuery 2 0 5 ReferenceError loa
  • 使用 javascript 更改 div 颜色

    div style height 20px width 100 background color 000000 div br
  • 在 Javascript 中获取第一个数字出现后的子字符串

    我正在尝试提取第一个数字之后 并包括 的字符 ABC 123SD gt 123SD 123 gt 123 123SD gt 123SD ABC gt 我当前的解决方案如下 var string1 ABC 123SD var firstDig
  • Angular 2 Material 2 日期选择器日期格式

    我不知道如何更改材料2日期选择器的日期格式 我已阅读文档 但我不明白我实际上需要做什么 datepicker默认提供的输出日期格式为f e 6 9 2017 我想要实现的目标是将格式更改为类似的格式9 Jun 2017或任何其他 文档htt
  • 在 javascript、jQuery 或 css 中,如何让 div 或 iframe 展开以填充其余空间

    我有三个 iframe 我将顶部 iframe 设置为 50px 高度 将底部 iframe 设置为 50px 但我希望中间 iframe 扩展以填充其余空间 有没有一种技术可以用来对任何窗口屏幕尺寸执行此操作 谢谢 example
  • 如何防止 gulp-notify 破坏 Windows 中的 gulp-watch?

    我正在使用吞咽通知 https www npmjs org package gulp notify插入 这是我如何在 gulpfile js 中实现它的示例 您可以看到我也在使用 gutil 和 livereload 我不知道它们是否发挥任
  • Jest - 模拟函数,从另一个文件导入

    测试的文件使用从另一个文件导入的函数 import myFunc from myFile 如何在该文件的测试中模拟该函数的返回值 我正在使用笑话 这对我有用 我不确定这是否是一个好的做法 import as myFile from myFi
  • 在鼠标光标位置添加 cytoscape 节点

    我想在画布上的单击事件上的鼠标箭头位置添加一个 cytoscape 节点 我怎样才能做到这一点 我的方法 效果不太好 我可以通过单击创建一个节点 但无法确保创建的节点的位置位于我单击的位置 使用这样的东西 cy click function
  • 如何导入和导出 javascript ES6 类

    我是 javascript 和 nodejs 的新手 我正在使用这个项目来发展我的技能并学习新技术 目前我的项目使用多个相互依赖的类 类文件位于不同的目录中 我当前正在尝试使用 export 和 require 语句来允许在其他文件中引用类
  • Chrome 扩展同步调用 - 仅在窗口关闭后创建窗口

    我有这个代码 function voteNewWindow mailNum chrome windows create url http www google com incognito true function window conso
  • 如何在react-三纤维中提取并播放动画

    嗯 我有 gltf 动画模型 我成功加载模型 但无法播放嵌入的动画 我想知道是否可以以任何方式解决它 顺便说一句 我正在反应中工作 先感谢您 在这里您可以找到型号https drive google com file d 1ZVyklaQu
  • console.log() 显示同一对象属性的矛盾值

    我想我可能要疯了 我使用 console log 来查看对象的状态 然后在下一行对同一对象的特定属性执行 console log 并为每个属性获取不同的值 我正在使用的代码是 console log this pictures Items
  • 为什么 Web Worker 性能在 30 秒后急剧下降?

    我正在尝试提高在网络工作人员中执行时脚本的性能 它旨在解析浏览器中的大型文本文件而不会崩溃 一切都运行得很好 但我注意到使用网络工作者时大文件的性能存在严重差异 于是我做了一个简单的实验 我在同一输入上运行脚本两次 第一次运行在页面的主线程
  • Google 地图 API:忽略 DirectionService 请求中的季节性限制

    我目前正在开发一张地图 其中显示两点之间的最短路线 使用不同的交通工具 我注意到 有时 例如在冬季关闭的道路不会被考虑在内 我发现我可以使用方向服务 下面的代码 忽略高速公路 收费站和渡轮 但我一生都无法弄清楚如何 是否可以忽略季节性限制
  • 在不同环境中运行的react.js redux生产构建中将环境变量渲染到浏览器

    React redux realworld io 应用程序的自述文件位于https github com gothinkster react redux realworld example app https github com goth
  • 从 DirectionsRenderer 中获取折线或标记的事件

    我正在使用 DirectionsService 和路线方法来生成 DirectionsResult 我还使用 DirectionsRenderer 对象来显示结果 因为它非常易于使用 我在检测 Directions changed 事件时没
  • Knockout.js 安全绑定

    我想使用带有淘汰赛的安全绑定 为此我使用敲除安全绑定 js https github com brianmhunt knockout secure binding 谁能解释一下为什么下面的代码不起作用 它会抛出一个错误 未捕获 淘汰 安全
  • JavaScript 数组扩展语法的时间复杂度是多少?

    我想知道在 JavaScript 中使用数组扩展的时间复杂度是多少 是线性 O n 还是常数 O 1 下面的语法示例 let lar Math max nums 传播称为 Symbol iterator 有关对象的属性 对于数组 这将迭代数
  • useParams 钩子在 React 功能组件中返回未定义

    该应用程序显示所有照片

随机推荐

  • 微信公众号【OpenID详解】

    只知道 openID 是微信号加密后得到的 不同的公众号获取得微信号openID不同 但 UnionID 是一样的 微信openid由用户id和公众号id加密而来 同一用户相对同一公众账号的openid是不变的 对于不同公众号 同一用户的o
  • Learning OpenStack Keystone

    Author 海峰 http weibo com 344736086 http yanheven github io http blog csdn net yanheven1 这周重新学习整理了OpenStack Keystone里面的知识
  • CentOS没有了用什么?Rocky Linux 8.6安装体验

    2020 年 12 月 8 日 CentOS 项目宣布 CentOS 8 将于 2021 年底结束 而 CentOS 7 将在其生命周期结束后停止维护 CentOS 7 9 和 CentOS 8 5 将是最后的2个CentOS 版本 官方解
  • concurrentHashMap解析这篇文章就够了

    实现原理 ConcurrentHashMap使用分段锁技术 将数据分成一段一段的存储 然后给每一段数据配一把锁 当一个线程占用锁访问其中一个段数据的时候 其他段的数据也能被其他线程访问 能够实现真正的并发访问 如下图是ConcurrentH
  • 使用 Python 操作 MongoDB

    使用 Python 操作 MongoDB MongoDB 是一个开源的面向文档的 NoSQL 数据库 它具有高性能 可扩展性和灵活性的特点 通过使用 Python 的 pymongo 模块 我们可以方便地操作 MongoDB 数据库 本文将
  • CPU工作原理和MMU初探

    具体相关内容主要参考自一篇博客 当然有结合其它内容 感谢博主提供的资源 这里附上参考链接 http www cnblogs com xiangtao archive 2013 04 11 3014815 html 关于CPU和MMU需要做几
  • 企业微信第三方应用-应用客服会话(h5)

    企业微信中第三方应用 h5 不能像小程序那样将button标签的open type属性设置为contact即可跳转到客服会话页面 但是js sdk为了开发者提供了openThirdAppServiceChat Api 让用户可快速打开应用客
  • IT项目管理作业五

    一 你联合同学做一个年级微信公众号加强各班相互了解 联合活动 等 请写一份两页的报告 描述收集需求的方法 并附上收集的 需求跟踪矩阵 不少于五个需求 收集需求的方法 数据收集方面 头脑风暴 召集项目所有的参与成员 共同讨论关于微信公众号对于
  • Python Class

    关键字1 self self指代 类的实例化 而不是类本身 class Test def prt self print self print self class t Test t prt result
  • 从事Java三年多,去应聘16k最后没被录用,细节如下……

    前言 今天小编和大家分享一位以前面试的一位应聘者 工作4年26岁 统招本科 以下就是他的简历和面试情况 基本情况 专业技能 1 熟悉Sping了解SpringMVC SpringBoot Mybatis等框架 了解SpringCloud微服
  • 和平精英服务器位置,和平精英音乐盒在哪里 地图详细位置介绍

    和平精英体验服最近重新开放服务器 不少玩家在游戏中发现了新内容 特别是热度特别高的万圣节模式 很多小伙伴会问和平精英音乐盒在哪里 快随小编来看看吧 在所有地图的一些房区里面是会随机刷新出音乐盒的 当我们发现音乐盒后是可以与这个道具互动的 我
  • 2023前端面试题——JS篇

    1 判断 js 类型的方式 1 typeof 可以判断出 string number boolean undefined symbol 但判断 typeof null 时值为 object 判断数组和对象时值均为 object 2 inst
  • 避免陷入信息茧房

    目录 一 什么是信息茧房 二 做什么容易陷入信息茧房 三 如何避免陷入信息茧房 总结 一 什么是信息茧房 信息茧房 Echo Chamber 是指在社交媒体和互联网环境中 个体被限制在一种信息和观点的环境中 与自己持相似观点的人群形成闭环
  • 目标文件格式分析工具: ar,nm,objdump,objcopy,readelf

    http www kgdb info linuxdev object analyse tools 目标文件格式分析工具 ar nm objdump objcopy readelf 2011年9月5日 reship 发表评论 阅读评论 本文转
  • 推荐算法:基于内容的推荐_1:内容推荐算法

    基于内容的推荐 推荐给用户他们过去喜欢的类似产品 基于CF的推荐 识别出具有相同爱好的用户 给他们推产品 基于内容的推荐算法 基于内容推荐的步骤 对数据内容分析 得到物品的结构化描述 分析用户过去的评分或评论过的物品的 作为用户的训练样本
  • nabc模型_WHϵÁÐÔ²»¡Ô²ÖùÎϸ˼õËÙ»ú3DÁ¢ÌåÄ£ÐÍ_¼õËÙ»ú_¼õËÙÆ÷_Öйú¼õËÙ»úÐÅÏ¢Íøwww.jiansuji001.com...

    OzsgSFNGIFYxMy4wNSAKSQAAAABCAFTjJb68dJO9QmDluwAAAD4nMQg TDeJPlp42ux9B0BU17bonjnnTC 0XobeYWYYYCiD2BGNhSYiKogoKqKCBStjixqj
  • vscode打开代码,注释中的中文显示乱码

    问题如下 np random seed 2017 瀹氫箟闅忔満鏁扮殑绉嶅瓙 INPUT CHANNELS 3 杈撳叆鏁版嵁鐨勬尝娈垫暟锛孯GB锛屼负3 OUTPUT MASK CHANNELS 1 瀹氫箟杈撳嚭mask鐨勬尝娈垫暟锛屽彧鏈変
  • String与StringBuffer的区别

    String 是一个常量 即一旦创建不可更改 输出结果为 helloworldjeok 看似 string变量name的值改变了 其实此name非彼name 输出结果为 sex hello worldjeok name hello worl
  • ocaml学习随笔-1

    utop let rec my listprint items match items with first the rest gt printf s n first my listprint the rest gt val my list
  • React入门笔记(二)

    React入门笔记 二 1 前情回顾 2 组件 3 视频教程地址 1 前情回顾 书接上回 React入门笔记 一 主要介绍React的基本特点 虚拟dom的实现原理 利用包管理工具搭建基本的React单页面引用等 如果你跳过了前面的项目配置