react框架学习总结(纯干货)

2023-11-15

首先,我先给出我学习react框架的参考教程,以下内容都是我依据此教程的个人总结。react教程

React与JSX:

function Square(props) {
    return (
        <button className="square" onClick={props.onClick}>
            {props.value}
        </button>
    );
}

React是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。JSX是JavaScript 的语法扩展,所以其也具有JavaScript 的全部功能,并且建议在React框架中配合使用 JSX,JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。
上述给出的一个奇怪的函数代码就是一个函数组件,它就是采用React框架的JSX语法,其主要体现在两点表现:一个是代码里直接嵌入HTML标签,另一个是{}里面可以嵌入表达式。这两点语法都是原生JavaScript语法所不具备的特性。
注意:jsx语法既可以写在jsx文件里也可以直接写在js文件下
其实简单看来,React框架主要功能体现在前端UI页面的渲染,包括性能优化以及操作简化等等方面。站在mvc框架的角度来看,React操作view层的功能实现。

搭建React环境:
方式一:在网站中添加React
添加一个 DOM 容器到 HTML并添加 相应的Script 标签:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>react-dom</title>
</head>

<body>
    <div id="like_button_container"></div>
    <!-- 加载 React。-->
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>

    <!-- 加载我们的 React 组件。-->
    <script src="like_button.js"></script>
</body>

</html>

创建一个 React 组件:

'use strict';

const e = React.createElement;

class LikeButton extends React.Component {
    constructor(props) {
        super(props);
        this.state = { liked: false };
    }

    render() {
        if (this.state.liked) {
            return 'You liked this.';
        }

        return e(
            'button',
            { onClick: () => this.setState({ liked: true }) },
            'Like'
        );
    }
}
const domContainer = document.querySelector('#like_button_container');
ReactDOM.render(e(LikeButton), domContainer);

直接运行打开html页面即可运行。
方式二:Create React App
此方式是通过IDE命令行的方式创建一个本地的React应用项目,也是最佳的创建方式,所以首先得在本地安装node(Node >= 8.10 和 npm >= 5.6)。
一切准备就绪后,只需一行代码即可搭建本地React框架:

npx create-react-app my-app

搭建ts版本的react框架(tsx):

npx create-react-app my-app --template typescript

这是搭建好的目录结构
jsx:
在这里插入图片描述

tsx:
在这里插入图片描述

项目框架搭建好后在src目录下添加我们自己的代码文件。
进入项目根目录并运行项目:

cd my-app
npm start

jsx:
在这里插入图片描述

tsx:
在这里插入图片描述
注:有关ts的具体详细内容我这里先暂不做讲解,如果大家有感觉到突兀可以先参看我给出的ts教程或者参看我下期编写的ts学习总结。
ts官方教程

组件与Props:
组件是React框架中最重要的概念之一,在博客最开始的时候也提到这个词,现在来详细的此概念。
组件的概念:组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。
在React框架里有两种组件:函数组件和类组件
这是函数组件:

function Square(props) {
    return (
        <button className="square" onClick={props.onClick}>
            {props.value}
        </button>
    );
}

这是类组件:

class Board extends React.Component {
    renderSquare(i) {
        return (
            <Square
                value={this.props.squares[i]}
                onClick={() => this.props.onClick(i)}
            />
        );
    }

    render() {
        return (
            <div>
                <div className="board-row">
                    {this.renderSquare(0)}
                    {this.renderSquare(1)}
                    {this.renderSquare(2)}
                </div>
                <div className="board-row">
                    {this.renderSquare(3)}
                    {this.renderSquare(4)}
                    {this.renderSquare(5)}
                </div>
                <div className="board-row">
                    {this.renderSquare(6)}
                    {this.renderSquare(7)}
                    {this.renderSquare(8)}
                </div>
            </div>
        );
    }
}

由上面的代码对比不难发现,函数组件适用于较为简单的功能组件,而类组件就适用于较为复杂的功能组件,类组件将在下一部分state和生命周期中具体讲解。
注意:为了更有效的区分普通函数与函数组件,所有的组件名称必须以大写字母开头。
Props:这是由React内部包装设置的一个用于传递数据的参数,Props最大的特点就是read only,即Props只能被读取使用但是不能被修改

State和(类组件)生命周期:
什么是State:Props只能读取不能修改,显然肯定满足不了用户的需求。为了满足React 组件随用户操作、网络响应或者其他变化而动态更改输出内容的功能,State出现了,它可以用户自定义。State可以被修改,但是不能直接修改,只能通过setState()函数来修改State里面的值,这也是State和Props最大的区别。
组件的生命周期:由于函数组件过于简单而这里的生命周期是指一些声明周期方法,所以这里的生命周期对于类组件而言。
组件的生命周期分为三个周期:挂载,更新和卸载。
这里的生命周期方法我不做具体讲解,大家可以参看详细的官方教程。
挂载,当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

注意:render()方法是类组件中唯一必须实现的方法。因为最简单的函数组件里面的业务逻辑也包含reader()方法的业务逻辑。如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。
更新,当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

注意:此处说的props改变与上述说的props不可修改并不矛盾,上述说的props不可修改是指props在当前组件中不能被修改,而此处说的props改变是指在父组件因为传递参数的内容改变而导致子组件props改变。
卸载,当组件从 DOM 中移除时会调用如下方法:

  • componentWillUnmount()


事件处理:
React元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:

  • React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
  • 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。

React元素的事件处理中this绑定的三种方式:
es5中的bind方法:

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

public class fields 语法:

class LoggingButton extends React.Component {
  // 此语法确保 `handleClick` 内的 `this` 已被绑定。
  handleClick = () => {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

箭头函数:

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // 此语法确保 `handleClick` 内的 `this` 已被绑定。
    return (
      <button onClick={() => this.handleClick()}>
        Click me
      </button>
    );
  }
}


一些其它的核心概念:
元素渲染: ReactDOM.render()是最顶层的渲染方法,而组件里面的render方法可以看成它的子成员,ReactDOM.render是唯一一个直接与DOM交互的方法,而其字render方法只改变ReactDOM元素,最终都是由ReactDOM.render来更替UI的DOM元素,所以此方法建议只调用一次。
条件渲染:React 中的条件渲染和 JavaScript 中的一样,使用 JavaScript 运算符 if 或者条件运算符(包括三目运算符)去创建元素来表现当前的状态,然后让 React 根据它们来更新 UI。

render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;
    // 运算符 if
    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }
    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
  
  function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      // 条件运算符
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
}

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
    // 三目运算符
      {isLoggedIn
        ? <LogoutButton onClick={this.handleLogoutClick} />
        : <LoginButton onClick={this.handleLoginClick} />
      }
    </div>
  );
}

状态提升:多个组件需要反映相同的变化数据,这时我们将共享状态提升到最近的共同父组件中去。状态提升体现的是种代码设计思想,此思想既能降低代码的耦合性还能提高代码的扩展性。
React有十分强大的组合模式。我们推荐使用组合而非继承来实现组件间的代码重用。


一个完整的较为全面覆盖的simple:
这是官网教程给出的一个井字棋游戏simple,几乎涵盖了我上面列出的所有知识点,甚至还有没提到的细节知识点。比较React是个很大的框架,我所列出的这些才只是冰山一角。
这个是游戏实现了四大功能:

  • tic-tac-toe(三连棋)游戏的所有功能
  • 能够判定玩家何时获胜
  • 能够记录游戏进程
  • 允许玩家查看游戏的历史记录,也可以查看任意一个历史版本的游戏棋盘状态

css代码:

body {
    font: 14px "Century Gothic", Futura, sans-serif;
    margin: 20px;
  }
  
  ol, ul {
    padding-left: 30px;
  }
  
  .board-row:after {
    clear: both;
    content: "";
    display: table;
  }
  
  .status {
    margin-bottom: 10px;
  }
  
  .square {
    background: #fff;
    border: 1px solid #999;
    float: left;
    font-size: 24px;
    font-weight: bold;
    line-height: 34px;
    height: 34px;
    margin-right: -1px;
    margin-top: -1px;
    padding: 0;
    text-align: center;
    width: 34px;
  }
  
  .square:focus {
    outline: none;
  }
  
  .kbd-navigation .square:focus {
    background: #ddd;
  }
  
  .game {
    display: flex;
    flex-direction: row;
  }
  
  .game-info {
    margin-left: 20px;
  }
  

js(jsx)代码:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
function Square(props) {
    return (
        <button className="square" onClick={props.onClick}>
            {props.value}
        </button>
    );
}

class Board extends React.Component {
    renderSquare(i) {
        return (
            <Square
                value={this.props.squares[i]}
                onClick={() => this.props.onClick(i)}
            />
        );
    }

    render() {
        return (
            <div>
                <div className="board-row">
                    {this.renderSquare(0)}
                    {this.renderSquare(1)}
                    {this.renderSquare(2)}
                </div>
                <div className="board-row">
                    {this.renderSquare(3)}
                    {this.renderSquare(4)}
                    {this.renderSquare(5)}
                </div>
                <div className="board-row">
                    {this.renderSquare(6)}
                    {this.renderSquare(7)}
                    {this.renderSquare(8)}
                </div>
            </div>
        );
    }
}

class Game extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            history: [
                {
                    squares: Array(9).fill(null)
                }
            ],
            stepNumber: 0,
            xIsNext: true
        };
    }

    handleClick(i) {
        const history = this.state.history.slice(0, this.state.stepNumber + 1);
        const current = history[history.length - 1];
        const squares = current.squares.slice();
        if (calculateWinner(squares) || squares[i]) {
            return;
        }
        squares[i] = this.state.xIsNext ? "X" : "O";
        this.setState({
            history: history.concat([
                {
                    squares: squares
                }
            ]),
            stepNumber: history.length,
            xIsNext: !this.state.xIsNext
        });
    }

    jumpTo(step) {
        this.setState({
            stepNumber: step,
            xIsNext: (step % 2) === 0
        });
    }

    render() {
        const history = this.state.history;
        const current = history[this.state.stepNumber];
        const winner = calculateWinner(current.squares);

        const moves = history.map((step, move) => {
            const desc = move ?
                'Go to move #' + move :
                'Go to game start';
            return (
                <li key={move}>
                    <button onClick={() => this.jumpTo(move)}>{desc}</button>
                </li>
            );
        });

        let status;
        if (winner) {
            status = "Winner: " + winner;
        } else {
            status = "Next player: " + (this.state.xIsNext ? "X" : "O");
        }

        return (
            <div className="game">
                <div className="game-board">
                    <Board
                        squares={current.squares}
                        onClick={i => this.handleClick(i)}
                    />
                </div>
                <div className="game-info">
                    <div>{status}</div>
                    <ol>{moves}</ol>
                </div>
            </div>
        );
    }
}
// ========================================

ReactDOM.render(<Game />, document.getElementById("root"));

function calculateWinner(squares) {
    const lines = [
        [0, 1, 2],
        [3, 4, 5],
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7],
        [2, 5, 8],
        [0, 4, 8],
        [2, 4, 6]
    ];
    for (let i = 0; i < lines.length; i++) {
        const [a, b, c] = lines[i];
        if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
            return squares[a];
        }
    }
    return null;
}

最后,由于我也只是个React初学者,此篇博客里面含有很多我自己的理解成分,难免会有错误理解,如果有发现错误的朋友欢迎评论区指出。路漫漫其修远,此篇博客的内容才只是React框架的冰山一角,希望能对大家有所帮助。

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

react框架学习总结(纯干货) 的相关文章

  • Spring Boot 笔记 注解 (三)

    Spring Beans 和 依赖注入 您可以自由地使用任何标准Spring框架技术来定义您的bean和它们 的 bean的 依赖项注入 为了简单起见 我们经常发现使用 ComponentScan 查找bean 使用 Autowired 用
  • linux下libusb的安装与测试

    2013 5 14 0 libusb的介绍 参考 1 1 环境 vmware fedora 10 linux 2 6 x 2 获取源代码 http sourceforge net projects libusb 最好选择libusb 1 0

随机推荐

  • 专升本——虚拟语气

    文章目录 1 if引导的虚拟语气 1 1 含义 1 2 公式表 1 3 练习 1 4 if的三种变形 1 5 练习2 2 wish的虚拟 2 1 含义 2 2 公式表 2 3 注意 用法同wish 2 4 练习 3 命令式虚拟 3 1 hi
  • 阿里云新ECS配置使用SSH连接

    本文使用实例系统为Ubuntu 18 04 64位 新实例创建完成后 去控制台操作 gt 更多 gt 密码 gt 重制实例密码设置新的密码 然后重启实例 此时要是直接通过ssh登陆 无法连接且有如下提示 ssh root xxx xx xx
  • 如何解决UE5重定向后丢失RootMotion

    解决方法如图所示
  • 有关无人机的几点总结

    Pix APM 减震问题 X Y 方向震动必须小于0 3g Z方向必须小于0 5g 最好每个方向上都控制在0 1g 电机动平衡处理 T motor 在工厂已经做过动平衡处理 ArduPilot 4 0 代码中初始化函数已经移至 AP veh
  • linux中yum -y install mysql为什么默认是mariadb?以及mysql yum源的配置

    linux自带yum源中mysql是什么版本 答案是 mariadb 我们可以从yum中的命令告诉我们 例如下 root dr yum repos d yum provides mysql 已加载插件 fastestmirror Loadi
  • OpenSSL 远程升级到 3.2.1

    OpenSSL 远程升级到 3 2 1 文章目录 OpenSSL 远程升级到 3 2 1 背景 升级 OpenSSL 1 查看 OpenSSL版本 2 下载最新稳定版本 OpenSSL 3 解压缩 安装 4 配置 背景 最近的护网行动 被查
  • 【实际开发19】- 压测 / 调优准备

    目录 1 Jmeter 2 Jmeter 环境部署 1 配置 临时修改语言 Options Choose Language Chinese 3 Jmeter 并发测试 0 提示 Postman 测试是 串行 的 无法测试并发请求 1 dai
  • Windows常用批处理命令

    前言 批处理文件是一个 bat 结尾的文本文件 这个文件的每一行都是一条DOS命令 可以使用任何文本文件编辑工具创建和修改 批处理是一种简单的程序 可以用 if 和 goto 来控制流程 也可以使用 for 循环 批处理的编程能力远不如C语
  • three.js 载入 3D 模型的方法

    three js 载入 3D 模型的方法有很多种 以下是其中的一些 1 OBJLoader模型加载器 import OBJLoader from three examples jsm loaders OBJLoader js 创建一个 OB
  • 多元统计分析(1)

    多元统计分析 1 概述 多元数据的描述与展示 随机变量的特征 随机变量 Y 独立同分布的随机样本 y 1 y 1 y1
  • 一般熟练盲打需要多久_话说。。用五笔打字的筒子们。。你们练了多久才能熟练的打出字啊。。...

    俺一直用的搜狗 但是最近想练习着用五笔 因为搜狗打人名啊什么的真的是挺不方便的 但是练五笔练了几天 感觉字都不会写了 打字之前先在脑子里过一遍这个字怎么写 有的简单的字都要想好几遍才能想明白 渐渐的信心都没了 所以想上来问问用五笔打字的筒子
  • mysql踩坑----case when then用法

    一 踩坑sql UPDATE bz order SET payment code CASE WHEN payment name APPPayPal THEN paypal WHEN payment name AfterpayAfterpay
  • Centos6.5镜像换源

    base name CentOS 6 5 baseurl http mirrors aliyun com centos vault 6 5 os basearch gpgcheck 1 enabled 1 gpgkey http vault
  • c语言编程 scant,TscanCode静态代码扫描软件v2.1

    TscanCode是腾讯静态分析团队开发的一款开源免费的C C 静态分析工具 由于其比较简单实用 准确率较高 并且扫描C C 代码不需要进行编译 对于开发与测试人员从代码层面挖掘问题有着很好的帮助 感兴趣的朋友快来下载试试吧 软件简介 Ts
  • Ruff:物联网+区块链的无限可能不靠炒作

    5月初 Ruff 与施耐德电气正式签订物联网合作协议 两家企业将在未来携手共筑工业物联网 共同推进工业物联网目标的快速实现 6月6日 Ruff 受邀出席 GBLS全球无眠区块链领袖峰会 并在大会上发表关于 区块链的供应链金融 主题演讲 与此
  • JavaScript常用的Hook脚本

    headers hook 当header中包含Authorization时 则插入断点 var code function var org window XMLHttpRequest prototype setRequestHeader w
  • 蓝桥杯-零基础python刷题之路-字符串冒泡排序(包含各个知识点详细记录)

    题中提到冒泡排序 先搞定一下冒泡排序 在找出题目中所需字符串 a 冒泡排序 如字符串 qiao 如果是冒泡排序 需要如下操作 1 iqao 2 iaqo 3 iaoq 4 aioq 冒泡排序走一遍数组 每次将两个字符进行比较 将大的放在后面
  • 2021-09-22

    AR1Int g0 0 0Ip address 192 168 1 1 24Int g0 0 1Ip address 20 20 30 97 30AR2Int g0 0 0Ip address 20 20 30 98 30Int g0 0
  • ThinkPHP5.0完全开发手册——调试模式

    调试模式 ThinkPHP有专门为开发过程而设置的调试模式 开启调试模式后 会牺牲一定的执行效率 但带来的方便和除错功能非常值得 我们强烈建议ThinkPHP开发人员在开发阶段始终开启调试模式 直到正式部署后关闭调试模式 方便及时发现隐患问
  • react框架学习总结(纯干货)

    首先 我先给出我学习react框架的参考教程 以下内容都是我依据此教程的个人总结 react教程 React与JSX function Square props return