好了,俺要开始学习React了 (基础一)

写前话痨

为啥俺开始学习React了,讲白了,就是为了适应这个 卷的时代 ,既然俺不能也不可能让这个时代去适应俺,那俺就能 热脸贴着冷时代(冷屁股) 了,还是嘎嘎会贴的那种😁

个人理解

俺之前的主打一直是vue,项目也都是围绕vue写的,其他的框架学了也用不上,纯属浪费时间。但现在很多招聘信息上都加上 Vue + React ,不学不行呀,像我这种菜鸟程序员,只会 Ctrl+C+V 的那种,不多学点技术绑在身上,出去就是饿死🙄

接触了一段时间的React开发后,从刚开始的不太适应(毕竟用Vue有小几年了),到慢慢觉得,你还别说,还真滴挺香的😍,有点爱不释手了,真的。但要想取代俺的主打框架Vue,还有待进一步验证。

学前准备

  • 开发工具: VSCode ;
  • 开发环境: 俺的node版本是16.20.0的,个人建议版本 >=16.x 就行了 Node.js (nodejs.org) ;
  • 俺叫它代码提交工具: git Git (git-scm.com) ;
  • VSCode插件拓展:

Simple React Snippets,可通过缩写快速生成React相关的代码片段

Auto Import - ES6, TS, JSX, TSX,可自动引入React相关依赖

Prettier - Code formatter,可自动格式化代码

Error Lens,错误行代码高亮提示错误

CodeGeeX: AI Code AutoComplete, Chat, Auto Comment,代码智能提示工具

Auto Close Tag,自动关闭标签,在开始标记的结束括号中键入后,将自动插入结束标记

ESLint,自动检测不符合规范的代码

JavaScript (ES6) code snippets,ES6 语法中的 JavaScript 代码片段提示

Night Owl,设置编辑器颜色主题

  • node版本管理工具: 两种工具都可,看个人意愿吧,俺用的是 nvm
  1. nvm nvm for windows 下载、安装及使用 - 掘金 (juejin.cn) ;
  2. volta 还在用nvm做node管理工具?快来试试Volta吧! - 掘金 (juejin.cn) ;

开始入坑

网上有很多对React的介绍,俺这就不多说了。这里俺一个不吱声,直接给俺看官网: React ; 直到看到它想吐,那就牛逼了😎

create-react-app 脚手架

  1. 采用脚手架创建项目:react-basics
bash 复制代码
$ npx create-react-app react-basics

将代码和文件该删的删,该留的留: 如下结构

App.js为根组件,并在index.js文件中渲染

React三大API

index.js 中就可以看到两个:

js 复制代码
import ReactDOM from "react-dom/client";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);

ReactDOM.createRoot(): 获取根元素,根元素就是React元素要插入的位置

root.render(): 用来将React元素渲染到根元素中,根元素中所有的内容都会被删除,被React元素所替换,当重复调用render()时,React会将两次的渲染结果进行比较,他会确保只修改那些发生变化的元素,对DOM做最少的修改。

除了这两个还有一个:- React.createElement(): 用来出创建一个React元素:

参数:

  1. 元素名(组件名、html标签必须小写)

  2. 元素的属性

  3. 在设置事件时

    • 事件名使用驼峰命名法,后面跟事件函数
    • 在设置class时,class使用className
  4. 元素的子元素(内容)

注意点:React元素最终会通过虚拟DOM转化为真实的DOM元素;React元素一旦创建无法修改,只能通过新创建的元素进行替换,例如:

js 复制代码
// 创建一个div
const div = React.createElement("div", {}, "Hello World", button);

JSX注意事项

  1. JSX不是字符串,不要加引号

  2. JSX中html标签应该小写,React组件应该大写开头

  3. JSX中有且只有一个根标签

  4. JSX的标签必须正确结束(自结束标签必须写/)

  5. 在JSX中可以使用{}嵌入表达式

    有值的语句的就是表达式

  6. 如果表达式是空值、布尔值、undefined,将不会显示

  7. 在JSX中,属性可以直接在标签中设置

    注意:

    class需要使用className代替

    style中必须使用对象设置style={{background:'red'}}

  8. 渲染列表:{} 只能用来放js表达式,而不能放语句(if for),但在语句中是可以去操作JSX

虚拟DOM

  • 在React我们操作的元素被称为React元素,并不是真正的原生DOM元素,React通过虚拟DOM 将React元素 和 原生DOM,进行映射,虽然操作的React元素,但是这些操作最终都会在真实DOM中体现出来。

  • 虚拟DOM的好处:

    1. 降低API复杂度
    2. 解决兼容问题
    3. 提升性能(减少DOM的不必要操作)
  • 每当我们调用root.render()时,页面就会发生重新渲染,React会通过diffing算法,将新的元素和旧的元素进行比较,通过比较找到发生变化的元素,并且只对变化的元素进行修改,没有发生的变化不予处理

例子:将 const data = ['孙悟空', '猪八戒', '沙和尚']; 用列表展示:

js 复制代码
function App() {
  const data = ["孙悟空", "猪八戒", "沙和尚"];
  return (
    <div className="App">
      hello world!
      <ul>
        {data.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;

当重新再用当前一样的数据再渲染一次,比较两次数据时,React会先比较父元素,父元素如果不同,直接所有元素全部替换,父元素一致,在去逐个比较子元素,直到找到所有发生变化的元素为止,上例中,新旧两组数据完全一致,所以没有任何DOM对象被修改。

当我们在JSX中显示数组时,数组中每一个元素都需要设置一个唯一key,否则控制台会显示红色警告。

当在列表的最后添加了一个新元素时:

js 复制代码
function App() {
  const data = ["孙悟空", "猪八戒", "沙和尚"];
  const addDataHandler = () => {
    data.push("唐三藏");
    console.log(data);
  };
  return (
    <div className="App">
      hello world!
      <ul>
        {data.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
      <button onClick={addDataHandler}>添加</button>
    </div>
  );
}

export default App;

运行项目,打开控制台:

state 数据发生变化时自动重新渲染

你看,俺也向末尾添加数据了呀,为啥没有显示到页面去呢,你重写刷新页面也不行,data 是个死数据。这时我们就需要 state 数据发生变化时自动重新渲染:

  • 在React中,当组件渲染完毕后,再修改组件中的变量,不会使组件重新渲染

  • 要使得组件可以收到变量的影响,必须在变量修改后对组件进行重新渲染

  • 这里我们就需要一个特殊变量,当这个变量被修改时,组件会自动重新渲染

  • state相当于一个变量:

    • state只属于当前组件,其他组件无法访问。并且state是可变的,当其发生变化后组件会自动> 重新渲染,以使变化在页面中呈现
    • 只是这个变量在React中进行了注册,React会监控这个变量的变化,当state发生变化时,会自动触发组件的重新渲染,使得我们的修改可以在页面中呈现出来
  • 在函数组件中,我们需要通过钩子函数,获取state,使用钩子 useState() 来创建state,import {useState} from "react";

  • 它需要一个值作为参数,这个值就是state的初始值,该函数会返回一个数组,数组中第一个元素,是初始值,初始值只用来显示数据,直接修改不会触发组件的重新渲染,数组中的第二个元素,是一个函数,通常会命名为setXxx

  • 这个函数用来修改state,调用其修改state后会触发组件的重新渲染,并且使用函数中的值作为新的state值

state 的问题

  • state实际就是一个被React管理的变量,当我们通过setState()修改变量的值时,会触发组件的自动重新渲染
  • 只有state值发生变化时,组件才会重新渲染
  • 当state的值是一个对象时,修改时是使用新的对象去替换已有对象
  • 当通过setState去修改一个state时,并不表示修改当前的state,它修改的是组件下一次渲染时state值
  • setState()会触发组件的重新渲染,它是异步的,所以当调用setState()需要用旧state的值时,一定要注意,有可能出现计算错误的情况,为了避免这种情况,可以通过为setState()传递回调函数的形式来修改

来尝尝鲜:

js 复制代码
import { useState } from "react";

function App() {
  const [data, setData] = useState(["孙悟空", "猪八戒", "沙和尚"]);
  const addDataHandler = () => {
    // prevData为旧的data
    setData((prevData) => {
      return [...prevData, "唐僧"];
    });
  };
  console.log(data);
  return (
    <div className="App">
      hello world!
      <ul>
        {data.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
      <button onClick={addDataHandler}>添加</button>
    </div>
  );
}

export default App;

你会看到,在列表的最后添加了一个新元素,并没有改变其他的元素的顺序,在控制台中你会看到只是最后追加了新的 li ,所以这种操作不会带来性能问题。

但当在列表的最前边插入了一个新元素,你在看看:就是将 [...prevData, "唐僧"] 调换下位置

js 复制代码
setData((prevData) => {
      return ["唐僧", ...prevData];
    });

你看看,在列表的最前边插入了一个新元素,其他元素内容并没有发生变化,但是由于新元素插入到了开始位置,其余元素的位置全都发生变化,而React默认是根据位置比较元素,所以 此时,所有元素都会被修改,为了解决这个问题,React为列表设计了一个key属性,key的作用相当于ID,只是无法在页面中查看,当设置key以后,再比较元素时,就会比较相同key的元素,而不是按照顺序进行比较,在渲染一个列表时,通常会给列表项设置一个唯一的key来避免上述问题(这个key在当前列表中唯一即可)。

注意:

  1. 开发中一般会采用数据的id作为key
  2. 尽量不要使用元素的index作为key
  3. 索引会跟着元素顺序的改变而改变,所以使用索引做key跟没有key是一样的
  4. 唯一的不同就是,控制台的警告没了
  5. 当元素的顺序不会发生变化时,用索引做key也没有什么问题

下集精彩

屁股坐疼了,需要出门透透气,理解一下好不啦😁。下篇俺会讲到哪些知识点呢: 可能这篇已经涉及到一些下一篇的知识点了,没事,不用知道那些是为啥,只要懂得这篇的知识点就很棒了

  • React如何组件化:在代码示例中你可能也会看到组件化的大致结构长啥样了;
  • React如何定义事件:在代码示例中的button就添加了一个点击事件;
  • React如何组件通信;
  • React如何如何获取真实的DOM;
相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax