React 基础

文章目录

  • React是什么?
  • 1. JSX 简介
    • 1.1 在 JSX 中嵌入表达式
    • 1.2 JSX 中指定属性
    • 1.3 使用 JSX 指定子元素
    • 1.4 JSX 表示对象
  • 2. 元素渲染
      • 2.1 将一个元素渲染为 DOM
  • 3. 组件 & Props
    • 3.1 函数组件与class组件
      • 3.1.1 函数组件
      • 3.1.2 class组件
      • 3.2 渲染组件 & props
    • 3.1 Props的只读性
  • 4. State & 生命周期
    • 4.1 class 组件中的 state
      • 4.2 class组件中的生命周期
    • 4.3 正确使用State
      • 4.3.1 不要直接修改 State
      • 4.3.2 State 的更新可能是异步的
      • 4.3.3 State 的更新会被合并
    • 4.4 数据是向下流动的
  • 5. 事件处理
    • 5.1 基本使用
    • 5.2 class组件中的this问题
      • 5.2.1 使用bind来解决this问题
      • 5.2.2 使用类字段来解决this问题(常用)
      • 5.2.3 回调中使用箭头函数解决this问题
    • 5.3 向事件处理程序传递参数
  • 6. 条件渲染
    • 6.1 `if` 语句进行条件渲染
    • 6.2 与运算符 &&
    • 6.3 三目运算符
  • 7. 列表 & Key
    • 7.1 基础列表组件
    • 7.2 key
  • 8. 表单
    • 8.1 受控组件
    • 8.2 处理多个输入
  • 9. 状态提升
  • 10. 组合 vs 继承
    • 10.1 包含关系
  • 11. 样式
    • 11.1 行内样式
    • 11.2 class 类名

React是什么?

用于构建用户界面的 JavaScript 库

1. JSX 简介

1.1 在 JSX 中嵌入表达式

声明变量 name,并包裹在大括号中

const name = 'world';
const element = <h1>Hello, {name}</h1>;

在 JSX 语法中,你可以在大括号内放置任何有效的 JavaScript 表达式

1.2 JSX 中指定属性

可以使用大括号,来在属性值中插入一个 JavaScript 表达式:

const element = <img src={user.avatarUrl}></img>;

1.3 使用 JSX 指定子元素

JSX 标签里能够包含很多子元素:

const element = (<div><h1>Hello!</h1><h2>Good to see you here.</h2></div>
);

1.4 JSX 表示对象

const element = (<h1 className="greeting">Hello, world!</h1>
);

等效于:

const element = React.createElement('h1',{className: 'greeting'},'Hello, world!'
);

2. 元素渲染

2.1 将一个元素渲染为 DOM

页面根节点

<div id="root"></div>

将一个 React 元素渲染到根 DOM 节点中,只需把它们一起传入

const root = ReactDOM.createRoot(document.getElementById('root')
);const element = <h1>Hello, world</h1>;root.render(element);

3. 组件 & Props

组件允许你将 UI 拆分为独立可复用的代码片段,并对每个片段进行独立构思

3.1 函数组件与class组件

注意:组件名称必须以大写字母开头

3.1.1 函数组件

接受任意的入参(即 “props”)

function Welcome(props) {return <h1>Hello, {props.name}</h1>;
}

3.1.2 class组件

class Welcome extends React.Component {render() {return <h1>Hello, {this.props.name}</h1>;}
}

3.2 渲染组件 & props

当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”

const element = <Welcome name="Sara" />;

子组件(children)例子:

<Welcome name="react"><span>children</span>
</Welcome>

最终props为

{name: 'react', children: {}}

3.1 Props的只读性

组件无论是使用 函数声明还是通过 class 声明,都决不能修改自身的 props

纯函数:函数不会尝试更改入参,且多次调用下相同的入参始终返回相同的结果。
如:

function sum(a, b) {return a + b;
}

相反,下面这个则不是纯函数

function withdraw(account, amount) {account.total -= amount;
}

所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。

4. State & 生命周期

4.1 class 组件中的 state

class Clock extends React.Component {constructor(props) {super(props);this.state = {date: new Date()};}render() {return (<div><h1>Hello, world!</h1><h2>It is {this.state.date.toLocaleTimeString()}.</h2></div>);}
}

4.2 class组件中的生命周期

componentDidMount:方法会在组件已经被渲染到 DOM 中后运行
componentWillUnmount:方法会在组件卸载前调用

class Clock extends React.Component {constructor(props) {super(props);this.state = {date: new Date()};}componentDidMount() {}componentWillUnmount() {}render() {return (<div><h1>Hello, world!</h1><h2>It is {this.state.date.toLocaleTimeString()}.</h2></div>);}
}

4.3 正确使用State

4.3.1 不要直接修改 State

例如,此代码不会重新渲染组件:

// 错误
this.state.comment = 'Hello';

而是应该使用 setState():

// 正确
this.setState({comment: 'Hello'});

构造函数是唯一可以给 this.state 赋值的地方。

4.3.2 State 的更新可能是异步的

出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。
因为 this.propsthis.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
比如:

// 错误
this.setState({counter: this.state.counter + this.props.increment,
});

解决这个问题:
可以让 setState() 接收一个函数而不是一个对象

// Correct
this.setState((state, props) => ({counter: state.counter + props.increment
}));

4.3.3 State 的更新会被合并

当你调用 setState() 的时候,React 会把你提供的对象合并到当前的 state。

4.4 数据是向下流动的

5. 事件处理

5.1 基本使用

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

示例:

function MyButton() {function handleClick() {alert('You clicked me!');}return (<button onClick={handleClick}>Click me</button>);
}

5.2 class组件中的this问题

先来报错案例:
说明: JSX 回调函数中的 this,在 JavaScript 中,class 的方法默认不会绑定this

class Clock extends React.Component {constructor(props) {super(props);this.state = { message: 'hello' };}handleClick() {console.log(this) // 这里this为undefinedthis.setState({ message: '你好' })}render() {return (<div><h1>Hello, world!</h1><h2>It is {this.state.message}</h2><button onClick={this.handleClick}>点击事件</button></div>);}
}

5.2.1 使用bind来解决this问题

为了在回调中使用 this,对this.handleClick.bind(this);这个绑定是必不可少的

class Clock extends React.Component {constructor(props) {super(props);this.state = { message: 'hello' };// 为了在回调中使用 `this`,这个绑定是必不可少的this.handleClick = this.handleClick.bind(this);}handleClick() {console.log(this)this.setState({ message: '你好' })}render() {return (<div><h1>Hello, world!</h1><h2>It is {this.state.message}</h2><button onClick={this.handleClick}>点击事件</button></div>);}
}

5.2.2 使用类字段来解决this问题(常用)

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

5.2.3 回调中使用箭头函数解决this问题

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

5.3 向事件处理程序传递参数

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>

6. 条件渲染

6.1 if 语句进行条件渲染

function Greeting(props) {const isLoggedIn = props.isLoggedIn;if (isLoggedIn) {return <UserGreeting />;}return <GuestGreeting />;
}

6.2 与运算符 &&

render() {const count = 0;return (<div>{count && <h1>Messages: {count}</h1>}</div>);
}

6.3 三目运算符

render() {const isLoggedIn = this.state.isLoggedIn;return (<div>The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.</div>);
}

7. 列表 & Key

7.1 基础列表组件

使用 map 函数

function NumberList() {const numbers = [1, 2, 3, 4, 5];return (<ul>{numbers.map(item => {return <li>{item}</li>})}</ul>)
}

7.2 key

应当给数组中的每一个元素赋予一个确定的标识
一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串,最好是用id
注意,最好不要用索引index作为key,有可能会导致一些问题

function NumberList() {const numbers = [1, 2, 3, 4, 5];return (<ul>{numbers.map(item => {return <li key={item.toString()}>{item}</li>})}</ul>)
}

8. 表单

8.1 受控组件

渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。

class FormDemo extends React.Component {constructor(props) {super(props);this.state = {value: '',textAreaValue: '',selectValue: '',}}handleNameChange = (e) => {this.setState({ value: e.target.value })}handleTextAreaChange = (e) => {this.setState({ textAreaValue: e.target.value })}handleSelectChange = (e) => {this.setState({ selectValue: e.target.value })}handleSubmit = () => {alert('提交的 input:' + this.state.value)alert('提交的 textarea:' + this.state.textAreaValue)alert('提交的 select:' + this.state.selectValue)}render() {return (<form onSubmit={this.handleSubmit}><label>名字:<input value={this.state.value} onChange={this.handleNameChange}></input></label><br /><label>文章:<textarea value={this.state.textAreaValue} onChange={this.handleTextAreaChange} /></label><br /><label>选择你喜欢的风味:<select value={this.state.selectValue} onChange={this.handleSelectChange}><option value="grapefruit">葡萄柚</option><option value="lime">酸橙</option><option value="coconut">椰子</option><option value="mango">芒果</option></select></label><br /><input type="submit" value="提交" /></form>)}
}

8.2 处理多个输入

当需要处理多个 input 元素时,我们可以给每个元素添加 name 属性,并让处理函数根据 event.target.name 的值选择要执行的操作。

class Reservation extends React.Component {constructor(props) {super(props);this.state = {isGoing: true,numberOfGuests: 2};this.handleInputChange = this.handleInputChange.bind(this);}handleInputChange(event) {const target = event.target;const value = target.type === 'checkbox' ? target.checked : target.value;const name = target.name;this.setState({[name]: value});}render() {return (<form><label>参与:<inputname="isGoing"type="checkbox"checked={this.state.isGoing}onChange={this.handleInputChange} /></label><br /><label>来宾人数:<inputname="numberOfGuests"type="number"value={this.state.numberOfGuests}onChange={this.handleInputChange} /></label></form>);}
}

9. 状态提升

在 React 中,将多个组件中需要共享的 state 向上移动到它们的最近共同父组件中,便可实现共享 state。这就是所谓的“状态提升”
示例:

// 子组件 A
class A extends React.Component {constructor(props) {super(props);this.state = {};}handleClick = () => {// 这里调用父组件传过来的方法进行修改父组件的statethis.props.onGetAName('这是a传过来的')}render() {return (<div><h3>这是A组件</h3><button onClick={this.handleClick}>a按钮</button></div>)}
}// 子组件 B
class B extends React.Component {constructor(props) {super(props);this.state = {};}render() {return (<div><h3>这是B组件,接收a的数据:{this.props.name}</h3></div>)}
}// 父组件
class App extends React.Component {constructor(props) {super(props);this.state = {aName: ''};}getName = (val) => {this.setState({ aName: val })}render() {return (<div className="App"><A onGetAName={this.getName}></A><B name={this.state.aName}></B></div>)}
}

10. 组合 vs 继承

推荐使用组合而非继承来实现组件间的代码重用。

10.1 包含关系

组件使用一个特殊的 children prop 来将他们的子组件传递到渲染结果中:

function FancyBorder(props) {return (<div className={'FancyBorder FancyBorder-' + props.color}>{props.children}</div>);
}

这使得别的组件可以通过 JSX 嵌套,将任意组件作为子组件传递给它们。

function WelcomeDialog() {return (<FancyBorder color="blue"><h1 className="Dialog-title">Welcome</h1><p className="Dialog-message">Thank you for visiting our spacecraft!</p></FancyBorder>);
}

11. 样式

11.1 行内样式

{} 中绑定一个style对象

<h1 style={{ color: "red" }} onClick={this.click}>hello
</h1>

推荐:

const style = {fontSize: "50px",color: 'red'
};function App() {return (<div><h1 style={style}>这是 App</h1><Hello /></div>);
}

11.2 class 类名

  • 注意:这里绑定class要用 className
    .css
.title {color: red;
}

App.js

<h1 className="title" onClick={this.click}>hello
</h1>

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

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

相关文章

Windows 环境多个JDK安装与切换

一、下载jdk 去Oracle官网上下载想要安装的jdk版本&#xff0c;https://www.oracle.com/java/technologies/downloads/。 二、安装jdk 双击.exe文件&#xff0c;选择好安装目录进行安装。多个版本的jdk重复这两步操作就好。 三、多版本的jdk都下载安装完成之后&#xff0…

串口基本知识

概述&#xff1a; RS232适用于短距离通信&#xff0c;RS485适用于长距离的多点通信&#xff0c;而RS422适用于中长距离的高速通信。选择适合的串口标准应根据具体应用场景的需求来进行。 RS232的优缺点 RS-232采取不平衡传输方式&#xff0c;即所谓单端通讯。RS-232是为点对…

docker部署firefox浏览器,实现远程访问

拉取firefox镜像&#xff0c;部署代码 docker run -d --name firefox -e TZAsia/Hong_Kong -e DISPLAY_WIDTH1920 -e DISPLAY_HEIGHT1080 -e KEEP_APP_RUNNING1 -e ENABLE_CJK_FONT1 -e VNC_PASSWORD12345678ABCabc -p 5800:5800 -p 5900:5900 -v /docker/firefox/config:/…

构建免费的Dokan和WooCommerce构建线上课程市场在线销售数字课程

我们知道创建良好的学习说明和材料很困难。但当涉及到销售时&#xff0c;就变得更加困难。如果您无法出售您的课程&#xff0c;那么没有什么比这更令人沮丧的了。 幸运的是&#xff0c;如果您使用的是 WordPress 网站&#xff0c;那么您可以非常轻松且免费地完成此操作。借助L…

React使用Valtio的hook实现响应式状态管理

Valtio 是一个轻量级的库&#xff0c;可以在前端应用程序中管理状态。它的使用方式非常简单直观&#xff0c;让我们能够轻松跟踪和更新应用程序的状态&#xff0c;并且无需手动处理组件重新渲染的逻辑。假设我们正在构建一个社交媒体应用&#xff0c;我们想要追踪用户的信息、主…

Wargames与bash知识12

Wargames与bash知识12 Bandit20 关卡提示&#xff1a; 主目录中有一个setuid二进制文件&#xff0c;它执行以下操作&#xff1a;它在您指定为命令行参数的端口上连接到localhost。然后&#xff0c;它从连接中读取一行文本&#xff0c;并将其与前一级别的密码&#xff08;band…

【Angular教程 230106】03 Angular事件、表单事件、事件对象、双向数据绑定

Angular教程 230106#快捷 04 Angular事件、表单事件、事件对象、双向数据绑定&#xff08;45分&#xff09; 0 一些基础的概念 1 执行事件 (click)”getData()” 执行事件 angular 在 Angular 中&#xff0c;“执行事件”通常指的是当一个特定的事件发生时触发的一系列动作…

web学习笔记(十三)

目录 1.for循环 1.1格式&#xff1a; 1.2执行步骤&#xff1a; 1.3补充&#xff1a; 2. while循环和do-while循环 2.1格式&#xff1a; 补充断点调试&#xff1a; 补充穷举法&#xff1a; 1.for循环 1.1格式&#xff1a; for(变量初始化&#xff1b;判断条件&#xff1…

L1-005 考试座位号(Java)

题目 每个 PAT 考生在参加考试时都会被分配两个座位号&#xff0c;一个是试机座位&#xff0c;一个是考试座位。正常情况下&#xff0c;考生在入场时先得到试机座位号码&#xff0c;入座进入试机状态后&#xff0c;系统会显示该考生的考试座位号码&#xff0c;考试时考生需要换…

Ansys Zemax | 如何使用 ZPL 创建用户自定义求解

附件下载 联系工作人员获取附件 本文使用两个示例演示了如何使用 ZPL 创建用户自定义解。第一个示例介绍了如何创建 ZPL 解以确保序列文件中像面的曲率半径等于系统的 Petzval 曲率。第二个示例介绍了如何在非序列元件编辑器 ( Non-Sequential Component Editor ) 中基于其他…

含中间直流的三相电力电子变压器PET仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 背景&#xff1a; 目前高压电网中应用的绝大多数电力变压器都属于传 统电力变压器&#xff0c;传统变压器的优势在于工艺简单、安全性 较强。但传统变压器本身的弊端也非常突出&#xff0c;占地大、重 量大&…

从虚拟到现实:数字孪生驱动智慧城市可持续发展

随着科技的飞速发展&#xff0c;智慧城市已经成为未来城市发展的重要趋势。数字孪生技术作为智慧城市建设中的关键技术之一&#xff0c;正在发挥着越来越重要的作用。本文将探讨数字孪生如何从虚拟走向现实&#xff0c;驱动智慧城市的可持续发展。 一、数字孪生技术&#xff1…

【Vue3】2-6 : 计算属性与侦听器区别与原理(一)

本书目录&#xff1a;点击进入 一、计算属性 - computed:{} 1.1 目的 1.2 写法 代码 二、特征 2.1 调用时当属性调用 2.2 缓存 2.3 默认只读 2.4 可赋值&#xff1a;需要定义成对象&#xff0c;并写get&#xff0c;set方法 &#xff08;类似于java&#xff09; 三、原…

tryhackme--Command Injection(命令注入)

查看应用程序在哪个用户下运行。 任务1 简介&#xff08;什么是命令注入&#xff1f;&#xff09; 命令注入是滥用应用程序的行为&#xff0c;使用与设备上运行的应用程序相同的权限在操作系统上执行命令。例如&#xff0c;在以名为joe的用户身份运行的 Web 服务器上实现命令…

多层感知机(Multilayer Perceptron,MLP)

什么是机器学习 多层感知机&#xff08;Multilayer Perceptron&#xff0c;MLP&#xff09;是一种前馈神经网络&#xff0c;由输入层、多个隐藏层和输出层组成。MLP是一种强大的非线性模型&#xff0c;可以用于解决分类和回归问题。它通过学习适当的权重和偏置来映射输入到输出…

4.2 MATRIX MULTIPLICATION

矩阵-矩阵乘法&#xff0c;或简称矩阵乘法&#xff0c;在 i X j&#xff08;i 行 by j 列&#xff09;矩阵 M 和 j x k 矩阵 N 之间产生 i X k 矩阵P。矩阵乘法是基本线性代数子程序&#xff08;BLAS&#xff09;标准的重要组成部分&#xff08;见第3章中的“线性代数函数”边栏…

gazebo安装版本--公元2024年1月

不好意思我误导了各位&#xff0c;顺便也误导了我自己。。。。。。。。。 harmonic版本只适合单独使用&#xff0c;不适合与ros2配合仿真。 到2024年1月&#xff0c;只有fortress版本能与ros2配合使用

如何将 element-ui 中的 el-select 默认展开

<el-form-item label"藕粉桂花糖糕" prop"state" required><el-selectref"mySelect"v-model"form.state"style"width: 280px"placeholder"请选择"><el-option label"藕粉" :value"…

深信服防火墙转发到远端天融信防火墙内网应用卡顿问题解决

背景&#xff1a; 原来是天融信VPN&#xff0d;天融信VPN 做了一个内网应用NAT转发&#xff0c;用了多年应用都是正常的。近期一端改成了深信服务防火墙&#xff0c;用户反馈应用不正常&#xff0c;出现卡顿或直接不能访问&#xff0c;但涮新多次又可以访问。 解决&#xff1a…

Bito智能辅助编程体验报告

Bito智能辅助编程体验报告 1 Bito 能够为我们做些什么事&#xff1f; 号称 IDE 的“瑞士军刀”&#xff0c;可以提升开发 10 倍的效率; 生成代码&#xff1a;要求 Bito 使用自然语言提示生成任何语言的代码。&#xff08;例如&#xff0c;编写一个 Java 函数将数字从一种基数转…