React——简介、JSX、组件、传值 React Props、状态 React State

2023-11-10

环境搭建:

npm i -g create-react-app

create-react-app myapp

cd myapp

npm start

一、简介

1)简介

React主要用于构建UI。你可以在React里传递多种类型的参数,如声明代码,帮助你渲染出UI、也可以是静态的HTML DOM元素、也可以传递动态变量、甚至是可交互的应用组件。

React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。

2)特点

优势

  • 声明式设计 −React采用声明范式,可以轻松描述应用。

    命令式编程:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现。类似jquery 操作DOM,创建一个页面,一点点的告诉DOM 怎么去挂载,你要怎么去做;JQ\原生 都是命令式编程,都是在做DOM 操作。
    ​
    声明式编程:告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。
  • 高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。

    1.虚拟DOM(Virtual  DOM)
          用js 对象来模拟页面上的DOM 和DOM嵌套**实现DOM 元素的高效更新
    2.Diff 算法
             tree diff
             component diff
             element diff
    
  • 灵活 −React可以与已知的库或框架很好地配合。

  • JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。

  • 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。

  • 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

劣势

  • 学习成本很高,学习曲线很陡

  • react本身能做的事并不多,想做大东西必须得用react插件(全家桶)

二、JSX

(一) 介绍

 全称: JavaScript XML,是一个看起来很像 XML 的 JavaScript 语法扩展。

 优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。

  • 它是类型安全的,在编译过程中就能发现错误。

  • 使用 JSX 编写模板更加简单快速。

 作用:

     用来创建react虚拟DOM(元素)对象:

  • let el = <h1>Hello JSX!</h1>;

  • 注意1: 它不是字符串, 也不是HTML/XML标签

  • 注意2: 它最终产生的是一个JS对象

  • 标签名任意: HTML标签或其它标签

  • 标签属性任意: HTML标签属性或其它

  babel.js的作用:

  • 浏览器的js引擎是不能直接解析JSX语法代码的, 需要babel转译为纯JS的代码才能运行

  • 只要用了JSX,都要加上type="text/babel", 声明需要babel来处理

(二) JSX语法

  JavaScript + XML语法(HTML)

  解读jsx语法:

  1.遇到<>就会按照HTML语法解析为标签

  • 如果是html语法标准的标签就会解析为同名元素 (注意nav article等h5新标签名)
  • 如果是其他标签(组件)需要特别解析
  • <App/> 这个代码的意义是 new App()   <App num=200/> 相当于 new App(200)

  2.遇到以{开头的代码会按照JavaScript语法解析

  •  js代码包含在{}中

(三) 使用

可以将React JSX 代码可以放在一个独立文件上,并在不同的js文件中引入即可

App.js文件中:

//定义导出的标签
let App =(<div>
             <h1>标题</h1>
             <p>hahaha</p>
            </div>);
export default App; //将自定义的DOM元素暴露出来,供给其他的页面使用

index.js文件中:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
​
ReactDOM.render(
    App, 
    document.getElementById('root')
);

给根元素内部渲染组件模板的三种写法: 

//1. let App=<div>666</div>

//2.函数组件 function App(){
//   let a="hello"
//   return <div>666{a+"world"}</div>
// }

//3.导入对象组件: import App from "./App"

root.render(<App/>);  //给根元素内部渲染组件模板

 (四) 样式

  •  React 推荐使用内联样式

      App.css文件:

.adiv{
    color: pink;
}

     App.jsx文件:

import React from "react";
import "./App.css" //全局css样式
class App extends React.Component {
    constructor(arg) {
        super(arg)
    }
    render() {
        let box = "adiv"
        let bdiv = {
            color: "lightblue"
        }

        return (
            <div>
                <div className={box}>123</div>
                <div style={bdiv}>456</div>
            </div>
        )
    }
}
export default App;

 显示结果:

 (五) 注释

注释需要写在花括号中,需要注意的是:

  • 在标签内部的注释需要花括号

  • 在标签外的的注释不能使用花括号

ReactDOM.render(
    /*标签外部的注释 */
    <h1>我是标题 {/*标签内部的注释*/}</h1>,
    document.getElementById('root')
);

 (六) JavaScript 表达式

  • 我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。
let a=20
function fn(){return "hello"}
ReactDOM.render(
    <div>
      <h1>{a+1}</h1>
      <h3>{fn()}</h3>
    </div>,
    document.getElementById('root')
);

 (七)条件渲染

  1. 三目运算符

  • 在 JSX 内部不能使用 if else 语句,可以使用 三元运算 表达式来替代。
import React from "react";
class App extends React.Component {
    constructor(arg) {
        super(arg)
    }
    render() {
        let flag = false
        let a = "hi"
        let b = <h1>hi</h1>
        return (
            <div>
                {/* 三目运算符代替if-else */}
                <div>{flag ? a : b}</div>
            </div>
        )
    }
}
export default App;

   显示结果:

  

 2. 可以在JSX外部使用if语句

var i = 10;
if(i > 0){ //使用if语句的好处是:如果条件不满足且不需要渲染组件时不需要写else
    box = <div className="box"></div>;
}
ReactDOM.render(
    <div>
      { box }
    </div>,
    document.getElementById('root')
);

 (八)数组&列表渲染

  • JSX 允许在模板中插入数组,数组会自动展开所有成员
  • 通过数组的map函数
import React from "react";
class App extends React.Component {
    constructor(arg) {
        super(arg)
    }
    render() {
        let arr = ["a", "b", "c", <div>这是div标签</div>, "换行了"]
        let arr2 = ["hello", "react"]
        let arr3 = [{ id: 1, name: "haha" }, { id: 2, name: "xixi" }]
        return (
            <div>
                {/* 把元素从数组arr中取出来显示在div中 不需要for循环了 */}
                <div>{arr}</div>

                {/* 可以在渲染标签的时候写逻辑 */}
                <div>{arr2.map(el => <h3>{el}</h3>)}</div>
                <div>{arr3.map(el => <div><h2>{el.id}</h2><p>{el.name}</p></div>)}</div>
            </div>
        )
    }
}
export default App;

   显示结果:

面试题:为什么render函数返回的模板用()括起来?

答:因为js语法中return换行的话 认为是没有返回值的

三、组件

React.js 中一切皆组件,用 React.js 写的其实就是 React.js 组件。

我们在编写 React.js 组件的时候,一般都需要继承 React.js 的 Component(类定义)。一个组件类必须要实现一个 render 方法,这个 render 方法必须要返回一个 JSX 元素。但这里要注意的是,必须要用一个外层的 JSX 元素把所有内容包裹起来。返回并列多个 JSX 元素是不合法的。

1、定义单个组件

(1)定义组件

  • 方式1:通过React自定义组件(DOM元素):类定义

import React, { Component } from 'react'

export class Box extends Component {
  render() {
    return (
      <div>
        <h2>类组件--Box</h2>
      </div>
    )
  }
}

export default Box
  • 方式2:通过React自定义组件(DOM元素):函数定义

//普通函数
export default function Box2() {
    return (
        <div>
            <div>
                <h2>静态组件Box2--纯粹的静态模板</h2> 
                函数组件,无状态组件 pure
            </div>
        </div>
    )
}

//箭头函数
import React from 'react'
let Box3=()=>{return <div>Box3</div>}
export default Box3

(2) 使用组件

import React from "react";
import Box from "./Box";
import Box2 from './Box2'
import Box3 from './Box3'
class App extends React.Component {
    constructor(arg) {
        super(arg)
    }
    render() {
        return ( 
            <div>
                <Box></Box>
                <Box2></Box2>
                <Box3></Box3>
            </div>
        )
    }
}
export default App;

2、定义复合组件

可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离--组件嵌套

import React from 'react';
import ReactDOM from 'react-dom';
​
class WebSite extends React.Component {
    render() {
        return (
            <div>
                <Name name={this.props.name} />
                <Link site={this.props.site} />
            </div>
        );
    }
}
//局部组件Name
class Name extends React.Component {
    render() {
        return (
            <h1>{this.props.name}</h1>
        );
    }
}
//局部组件Link
class Link extends React.Component {
    render() {
        return (
            <h1>{this.props.site}</h1>
        );
    }
}
​
ReactDOM.render(
    <WebSite name="百度一下,你就知道" site='http://www.baidu.com' />, 
    document.getElementById('root')
)

四、传值 React Props

React 的一大特点是单向数据流

React 中的每一个组件,都包含有一个属性(props),属性主要是从父组件传递给子组件的,在组件内部,可以通过this.props获取属性对象。

1、定义和使用props 传值

   1)通过React类定义组件时:

  • 在父组件render 方法中调用组件时使用key=value 的形式来指定属性。

ReactDOM.render(
    <MyApp name="哈哈哈" />, 
    document.getElementById('root')
);
  • 在自定义子组件中通过this.props.key 来获得组件属性的值,需要使用{}括起来。
// 类定义组件时,使用属性 this.props.属性名称
class MyApp extends React.Component {
    render() {
        return (<p>{this.props.name}</p>);
    }
}

  2)通过React函数定义 组件时:

  • 在父组件render 方法中调用组件时使用key/value 的形式来指定属性。

ReactDOM.render(
    <Myfun title="哈哈哈" />, 
    document.getElementById('root')
);
  • 在自定义子组件中通过函数接收参数propsprops.key来获得组件属性的值,需要使用{}括起来

// 函数定义组件时,在组件内部使用属性值:props.属性名称
function Myfun(props) { // 函数需要传递一个参数props
    return(<h2>{props.title}</h2>)
}
​

2、默认Props

  • 定义默认props

父组件:

//由于是用ES6 class语法创建组件,其内部只允许定义方法,而不能定义属性,class的属性只能定义在class之外。所以defaultProps要写在组件外部。
App.defaultProps = {
    name: '哈哈哈'
};
    
ReactDOM.render(
    <App />,
    document.getElementById('root')
);

子组件:

class App extends React.Component {
    render() {
        return <p>my name is {this.props.name}</p>
    }   
}

3、多属性传值

(1)定义一个this.props对象,在对象中声明多个键值对,用于表示组件的属性

(2)在组件中使用{...this.props}的方式传递属性。“...”表示JSX的延展操作符,这种方式可以很方便的为组件指定多个属性,并且为属性的值指定数据类型。

父组件:

let p1 = {
    name: '哈哈哈', 
    age: 21,
    sex: '女'
};
​
ReactDOM.render(
    //<MyApp name='哈哈哈' age='21' sex='女' />
    <MyApp {...p1}/>,
    document.getElementById('root')
);

子组件:

class MyApp extends React.Component {
    render() {
        return(
            <h1>{this.props.name} : {this.props.age} : {this.props.sex}</h1>
        );
    }
}

五、状态 React State

1、定义State

React在ES6的实现中,规定state在constructor中实现

正确定义State的方式如下:

(1)在constructor中实现state

(2)在constructor中通过bind绑定事件函数(事件函数是用来改变状态)

(3)在事件函数内部使用setState函数更改状态

(4)在组件中的render函数中使用该状态

(5)在组件上需要设置监听事件,去触发事件函数的执行

//定义组件
class LikeButton extends React.Component {
    //constructor表示构造器,在constructor需要声明状态state,在声明state之前需要使用super(props);
	constructor(props) {
		super(props);//使用父类的属性
        
        //声明状态
		this.state = {
			liked: false
		}
		//Currently, you are calling bind. 
		//But bind returns a bound function. 
		//You need to set the function to its bound value.
		//目前,你正在调用绑定。但是绑定返回绑定函数。您需要将函数设置为其绑定值。
		this.handleClick = this.handleClick.bind(this);
	}
    
	handleClick(event) {
		this.setState({liked: !this.state.liked});
	}
    
	render() {
		return (
			<button onClick={this.handleClick}>
				你<strong>{this.state.liked ? '喜欢' : '不喜欢'}</strong>我,点我切换
			</button>
		)
	}
}

ReactDOM.render(
	<LikeButton />,
	document.getElementById('root')
)

2、setState设置状态

(1)语法:

      setState(object nextState[, function callback])

(2)说明:

  • setState是React事件处理函数中和回调函数中触发UI更新的主要方法。

  • 不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换。

  • setState()不一定是同步的,为了性能提升,React会批量执行state和DOM渲染。

  • setState()总是会触发一次组件重绘,但可在shouldComponentUpdate()中实现一些条件渲染逻辑来解决。

class MyApp extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            clickCount: 0
        };
​
        this.handleClick = this.handleClick.bind(this);
    }
​
    handleClick(event) {
        this.setState({clickCount: this.state.clickCount + 1});
    }
​
    render() {
        return (
            <h2 onClick={this.handleClick}>
                点击后次数变更: {this.state.clickCount}
            </h2>
        );
    }
}
​
ReactDOM.render(
    <MyApp />,
    document.getElementById('root')
);

同步设置多个状态时(不常用),可以在setState函数的第二个参数可以传递一个function回调函数,如下:

class MyApp extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            clickCount: 0, 
            isRed: false,
            smallFont: true
        };
​
        this.handleClick = this.handleClick.bind(this);
    }
​
    handleClick(event) {
        this.setState(
            {clickCount: this.state.clickCount + 1},
            function() {
                this.setState(
                    {isRed: !this.state.isRed}, 
                    function() {
                        this.setState({smallFont: !this.state.smallFont});
                    }
                );
            }
            
        );
        console.log(this.state.isred);
    }
​
    render() {
        var redStyle = {color: 'red', fontSize: 50};
        var blueStyle = {color: 'blue', fontSize: 14};
        return (
            <h2 onClick={this.handleClick} style={this.state.isRed ? redStyle : blueStyle}>
                点击后次数变更: {this.state.clickCount}
            </h2>
        );
    }
}
​
ReactDOM.render(
    <MyApp />,
    document.getElementById('root')
);

状态上移:当存在多个组件共同依赖一个状态,或是当子组件的props 数据需要被修改时,将这个状态放到对应组件的父组件中:

  子组件:

class Site extends React.Component {
    render() {
        return (
            <div>
                <button onClick={this.props.updateState}>点击改变</button>
                <h2>{this.props.myData}</h2>
            </div>
        );
    }
}

  父组件: 

class Content extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: 'hello'
        };
        this.handleChange = this.handleChange.bind(this);
    }
​
    handleChange(event) {
        this.setState({value: '你好'});
    }
​
    render() {
        return(
            <div>
                <Site myData={this.state.value} updateState={this.handleChange}/>
            </div>
        );
    }
}

3、State 与 Props 区别

除了State, 组件的Props也是和组件的UI有关的。他们之间的主要区别是:

  • props 中的数据都是外界传递过来的

  • state 中的数据都是组件私有的;(通过Ajax 获取回来的数据,一般都是私有数据)

  • props 中的数据都是只读的,不能重新赋值

  • state 中的数据都是可读可写的

  • State定义在constructor内部,在super(props)代码后面;Props默认值定义在类(组件)的外部

当子组件的属性值是可变值时,采用状态上移:

状态上移通过属性将父组件的状态传递到子组件,那么父组件的状态发生变化时,子组件的属性也会改变

4、state/props 实现父子组件通信

  • 子组件获取父组件整个组件进行传参

    • 父组件在调用子组件时,传入一整个组件给子组件<Children parent={ this } />

    • 父组件中定义一个方法getChildrenMsg(resulet, msg),用来获取子组件传来的值以及执行其他操作

    • 子组件在通过this.props来获取到一整个组件this.props.parent 或者this.props[parent]

    • 子组件调用父组件步骤2里定义的方法进行传值this.props.parent.getChildrenMsg(this,val)

  Parent:

import Children from './Children'
export default class Parent extends Component {
    constructor(props) {
        super(props)
        this.state = {
            msg: '父组件传值给子组件',
            childrenMsg: ''
        }
    }
​
    getChildrenMsg = (result, msg) => {
        // console.log(result, msg)
        this.setState({
            childrenMsg: msg
        })
    }
​
    render() {
        return (
            <div>
                <h2>我是父组件 </h2>
                <h3>子组件传来的值为:{ this.state.childrenMsg }</h3>
                <hr/>
                <Children parent={ this } />
                {/*<Children parent={ this.getChildrenMsg.bind(this) } />*/}
            </div>
        )
    }
}

  Children:

export default class Children extends Component {
    constructor(props) {
        super(props)
        this.state = {
            msg: '子组件传值给父组件'
        }
    }
​
    toParent = () => {
        // console.log(this.props.parent.getChildrenMsg.bind(this, this.state.msg))
        this.props.parent.getChildrenMsg(this, this.state.msg)
    }
​
    render() {
        return (
            <div>
                <h2>{ 我是子组件 }</h2>
                <button onClick={ this.toParent }>子组件传入给父组件</button>
            </div>
        )
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React——简介、JSX、组件、传值 React Props、状态 React State 的相关文章

随机推荐

  • 软件测试项目【金融、银行、电商、商城】

    项目经验 案例一 项目时间 2016 08 2017 07 项目名称 小花钱包 Web 项目描述 项目介绍 这个产品产是互联网金融理财服务平台 既可以发起投标 也可以借款 提供定期理财 活期理财等多种产品 平台主要有投资人 借款人 系统录入
  • 【虹软24届校招正式批】本周算法&;开发第二波笔试来袭

    今日更新提醒 看过了招聘信息 快来用牛客直投官网吧 打call 一键直投 给自己多一次面试机会 赞 移动端 https mnowpick nowcoder com m m 立得空间 C 开发技术面 1 项目中的线程池问题2 指针引用区别3
  • 1.fastadmin之Log日志使用

    要开始用fastadmin做小程序的后台 怎么说 这个框架封装的很好 对于我这种新手渣渣不太友好 惆怅 首先来谈谈日志的使用吧 如何打个log 一 概念 1 在控制器中声明 use think Log 2 log的方法 一般我使用log w
  • Spring Cloud获取本机IP地址

    最新的Spring Cloud获取本机的IP地址的配置文件如下 eureka instance hostname spring cloud client ip address lease renewal interval in second
  • 用Langchain构建一个阅读助手

    LangChain 是一个强大的框架 可以简化构建高级语言模型应用程序的过程 01 什么是Langchain LangChain是一个强大的框架 旨在帮助开发人员使用语言模型构建端到端的应用程序 它提供了一套工具 组件和接口 可简化创建由大
  • STM32CubeM的搭建以及基于HAL库实现LED闪烁

    文章目录 一 STM32的开发环境的搭建 1 安装jdk环境 2 安装STM32CubeMX 3 安装固件库 4 安装MDK5软件 二 利用工具生成点亮LED灯的代码 三 MDK5生成 hex文件 四 程序烧录 五 运行结果 六 MDK5模
  • 基于SimGAN网络的人眼数据生成方法_SimGAN原理_参考代码

    注 此文为复现sim GAN 参考了一些论文 博客 如有侵权请联系 我附上原出处 由于一些格式原因 文章有些部分会比较乱 请见谅 Learning from Simulated and Unsupervised Images through
  • 5个你不可不知的IE的bug及其解决方案

    E令人咬牙切齿的bug不胜枚举 其中IE6更是臭名昭著 令人发指 这里总结出IE下最为严重的5个bug 及其应对方案 1 IE6下无法显示png格式的透明信息 这个bug是众多网页设计师的噩梦 虽然可以采用gif代替 但是gif的表现力实在
  • Ubuntu之Docker安装

    1 先卸载旧版 如果没有的话 就直接执行第二步 apt get remove docker docker engine docker io containerd runc 这个命令用于在 Ubuntu 和其他基于 Debian 的 Linu
  • qt 储存库

    手动添加 储存库要定位一个储存有QT在线安装镜像的地址 打开 http download qt io static mirrorlist 这个网址 显示了各国的qt镜像站点 点击 HTTP 最终进到 online repository ht
  • [C语言]浮点型在内存中的存储

    在上一篇文章 我们讲述了整型在内存中的存储 这篇文章我们就一起来看一下 浮点型在内存中的存储 回顾 整型在内存中的存储 C语言 和我一起来认识 整型在内存中的存储 HY PIGIE的博客 CSDN博客 目录 1 浮点数家族 2 整型和浮点型
  • Envi5.3——高分二号PMS数据预处理

    首先第一步 打开数据open 以TIFF格式打开 开始进行正射校正 RPC正射工作流程 我们先对多光谱进行校正 输入需正射校正文件和DEM文件 在这里我们不用自带的2010年的DEM文件 点击下一步 在高级控制面板 输出像素大小为4米 图像
  • 用于非线性时间序列预测的稀疏局部线性和邻域嵌入(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 本文提出了一种基于字典的L1范数稀疏编码
  • 基于SpringBoot的特色农产品销售设计与实现

    摘 要 目前市场上众多的特色农产品销售系统存在种种不足 比如系统无需登录即可查看农产品卖家的联系方式 并且交易大多为线下交易 很难实现线上购买 物流配送 线上收货收款的功能 本系统提供线上购买服务 使用数据库进行订单管理 设计优化交互界面
  • 【成电860考研】经验贴汇总(公共课+专业课+复试)-扒遍所有网站:信软群、王道、知乎、csdn等,截止21年7月整理出的所有帖子-共15篇

    单词哥 2020跨考 背景 记得 18 年底的时候 好朋友那年考研 我闲的无事就拿他买的英 语一真题做了下 忘了哪一年的题了 不过结果还可以 这也为后来 辞职考研埋了根 由于长期从事英语相关的工作 而又想要圆自己大 学时学计算机的梦 说到底
  • es 中关于 term,match, text, keyword

    转自 https blog csdn net qq 38043440 article details 101678677 最近项目中使用了ElasticSearch 在使用基本的查询功能的时候 遇到些头疼的事情 有时候数据明明存在 用ter
  • ES命令: “track_total_hits“:true

    搜索type全部数据 GET test movie search 结果 took 2 耗费时间 毫秒 timed out false 是否超时 shards total 5 发送给全部5个分片 successful 5 skipped 0
  • vlc详细使用说明

    vlc的全名是Video Lan Client 是一个开源的 跨平台的视频播放器 VLC支持大量的音视频传输 封装和编码格式 完整的功能特性列表可以在这里获得http www videolan org vlc features html 下
  • 小米蓝牙耳机使用说明_小米真无线蓝牙耳机Air2 SE评测

    很多人都会把 小米Air2 SE 这款耳机 当成是上一代的阉割版本 其实完全没必要这么想 因为他们除了耳机有点像之外 其它几乎全不一样 甚至当两款独立的产品也是没问题的 这款耳机根据我的分析和体验 我觉得它在音质上和小米Air2s 几乎是差
  • React——简介、JSX、组件、传值 React Props、状态 React State

    环境搭建 npm i g create react app create react app myapp cd myapp npm start 一 简介 1 简介 React主要用于构建UI 你可以在React里传递多种类型的参数 如声明代