React基础详解(一)

news/2024/7/15 18:30:39 标签: react.js, javascript, 前端

        Hello World--在原生JS里面引入React

javascript"><div id="root"></div>
//React 的核心库,与宿主环境无关
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
//依赖核心库,将核心的功能与页面相结合
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
//如果使用的JSX语法,还需要引入babel转义
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script>
    //创建一个p元素
    var span = React.createElement("span", {}, "一个p元素");
    //创建一个H1元素
    var h1 = React.createElement("h1", {
        title: "第一个React元素"
    }, "Hello", "World", span)
    ReactDOM.render(h1, document.getElementById("root"))
</script>
1、React.createElement

创建一个React元素,称作虚拟DOM,本质上是一个对象

1)参数1:元素类型,如果是字符串,本质上是一个对象

2)参数2:元素的属性,一个对象

3)后续参数:元素的子节点

2、JSX

JS的扩展语法,需要使用babel进行转义

2.1 什么是JSX

Facebook起草的JS扩展语法

本质是一个JS对象,会被babel编译,最终会被转换成React.createElement

每个JSX表达式,有且仅有一个根节点:React.Fragment

每个JSX元素必须结束(XML规范)

2.2 在JSX中嵌入表达式

将表达式作为内容的一部分:null和undefined不会显示;

将表达式作为元素属性,属性使用小驼峰命名法;

防止注入攻击:自动编码;使用dangerouslyInnerHTML进行插入文本节点

javascript">import React from 'react'
import ReactDOM from 'react-dom'

const content = "<h1>测试测试</h1>"
const div = (
            <div dangerouslySetInnerHTML={{
                __html: content
            }}>
            </div>)

ReactDOM.render(div, document.getElementById("root"))
2.3 元素的不可变性

虽然JSX元素是一个对象,但是该对象中的所有属性不可更改

如果确实需要更改元素的属性,需要重新创建JSX元素

3、组件

组件:包含内容、样式和功能的UI单元

3.1创建一个组件

特别注意:组件的名称首字母必须是大写

3.1.1函数组件

返回一个React元素

3.1.2类组件

必须继承React.Component

必须提供render函数,用于渲染组件

javascript">import React from 'react'

export default class MyClassComp extends React.Component{
    constructor(props){
        super(props) //this.props = props
    }



    //该方法必须返回React元素
    render() {
        return <h1>类组件的内容,数字:{this.props.number}</h1>    
    }
}
3.2组件的属性

        对于函数组件,属性会作为一个对象的属性,传递给函数的参数

        对于类组件,属性会作为一个对象的属性,传递给构造函数的参数

注意:组件的属性,应该使用小驼峰命名法

3.3组件无法改变自身的属性

        之前学习的React元素,本质上,就是一个组件(内置组件)

        React中的哲学,数据属于谁,谁才有权利改动

React中的数据,自顶而下流动

4、组件状态

组件状态:组件可以自行维护的数据

组件状态仅在类组件中有效

状态(state),本质上是类组件的一个属性,是一个对象

4.1状态初始化
4.2状态的变化

不能直接改变状态:因为React无法监控到状态发生了变化

必须使用this.setState({})改变状态

一旦调用了this.setState,会导致当前组件重新渲染

javascript">handleClick = () => {
    this.setState({
        //参数prev表示当前的状态
        //该函数的返回结果,会混合(覆盖)掉之前的状态
        //该函数是异步执行
        n: this.state.n + 1
    }, () => {
        //状态完成改变之后触发,该回调运行在render之后
        //所有状态全部更新完成,并且重新渲染后执行
        console.log("state更新完成", this.state.n)
    })

    this.setState({
        n: this.state.n + 1
    })

    this.setState(cur => ({
        n: cur.n + 1
    }))
}
4.3组件中的数据

        1、props:该数据是由组件的使用者传递的数据,所有权不属于组件自身,因此组件无法改变该数组(如果给自定义组件传递元素内容,则React会将元素内容作为children属性传递过去)

javascript">import React from 'react'

export default function Comp(props) {
    console.log(props)
    return (
        <div className="comp">
            {props.children || <h1>默认值</h1>}
        </div>
    )
}

        2、state:该数组是由组件自身创建的,所有权属于组件自身,因此组件有权改变该数据

5、事件

在React中,组件的事件,本质上就是一个属性;按照之前React对组件的约定,由于事件本质上是一个属性,因此也需要使用小驼峰命名法

注意:如果没有特殊处理,在事件处理函数中,this指向undefined

        1、使用bind函数,绑定this

        2、使用箭头函数

javascript">handleClick = () => {
    this.setState({
        n: this.state.n + 1
    }, () => {
        //状态完成改变之后触发,该回调运行在render之后
        console.log(this.state.n)
    })
}

render() {
    console.log("render")
    return (
        <div>
            <h1>
                {this.state.n}
            </h1>
            <p>
                <button onClick={this.handleClick}>+</button>
            </p>
        </div>
    )
}
6、深入认识setState

setState ,它对状态的改变,可能是异步的

(异步:与同步相区别,由于JS是单线程的,执行顺序是从上到下的,同步就是没有阻塞的情况下从上到下执行,异步就是有阻塞的情况下,将阻塞的事件放进执行队列的微队列里面,等待宏队列执行完成后,再执行微队列里面的事件)

        如果改变状态的代码处于某个HTML元素的事件中,则其是异步的,否则是同步

        如果遇到某个事件中,需要同步调用多次,需要使用函数的方式得到最新状态

最佳实践:

1、把所有的setState当做是异步的

2、永远不要信任setState调用之后的状态

3、如果要使用改变之后的状态,需要使用回调函数(setState的第二个参数)

4、如果新的状态要根据之前的状态进行运算,使用函数的方式改变状态(setState的第一个函数)

React会对异步的setState进行优化,将多次setState进行合并(将多次状态改变完成后,再统一对setState进行改变,然后触发render)


http://www.niftyadmin.cn/n/5153105.html

相关文章

四路IC卡读卡器通信协议

1、摘要 Sle4442卡为256字节加密卡&#xff0c;存在读数据、写数据、保护数据以及密码操作。该卡在密码验证之前数据为只读状态&#xff0c;需要写入数据必须先进行密码验证&#xff0c;密码为3个字节&#xff0c;新卡初始密码为0xff&#xff0c;0xff&#xff0c;0xff。该读卡器…

将CCES里写的算法嵌入到SigmaStudio中方法

加我微信hezkz17进数字音频系统研究开发交流答疑群 CCES里写的算法如何嵌入到SigmaDSP中? 4 SigmaStudio Plug-In GenerationThe overall process of implementing a new Algorithm Plug-In within SigmaStudio is shownbelow:Code the module in C or assembly language i…

1822_使用python内置的库进行日期序列的生成

使用python的内置的库进行日期序列的生成 用到的库介绍 datetime 实现这样的功能其实只需要这一个库就够了&#xff0c;但是网络上找到的例程很多都额外增加了对time库的引用。只能说&#xff0c;这样不会出现错误&#xff0c;但是这样肯定会有一些计算资源上的消耗。 #!/u…

Python tempfile模块

tempfile 是 Python 标准库中的一个模块&#xff0c;用于创建临时文件和目录。它是一个有用的工具&#xff0c;用于在程序运行期间生成临时数据&#xff0c;如临时文件、目录或命名管道。这些临时资源通常在程序运行结束后会被自动删除&#xff0c;以帮助维护文件系统的干净和避…

Vue3.0 路由

简介 Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成&#xff0c;让用 Vue.js 构建单页应用变得轻而易举。功能包括&#xff1a; 嵌套路由映射动态路由选择模块化、基于组件的路由配置路由参数、查询、通配符展示由 Vue.js 的过渡系统提供的过渡效果细致的导航控…

宠物医院服务预约小程序的效果如何

随着养宠家庭增多及对爱宠的照顾加深&#xff0c;除了食品、服饰外&#xff0c;宠物医院近些年也迎来了较高发展&#xff0c;部分城市甚至聚集着众多品牌&#xff0c;以单店或多店品牌的方式拓展市场。 对宠物医院来说&#xff0c;一般都是拓展同市客户&#xff0c;或者多门店…

视频视觉效果制作After Effects 2023 MacOS中文

After Effects 2023是一款业界领先的动态图形和视觉特效软件。它提供了强大的工具集&#xff0c;帮助用户创建引人入胜的视觉效果、动态图形和电影级特效。新的版本带来了更快的渲染速度、增强的图像处理和优化的工作流程&#xff0c;使用户能够更高效地工作。无论您是在电影、…

全能数据分析软件 Tableau Desktop 2019 mac中文版功能亮点

Tableau Desktop 2019 mac是一款专业的全能数据分析工具&#xff0c;可以让用户将海量数据导入并记性汇总&#xff0c;并且支持多种数据类型&#xff0c;比如像是编程常用的键值对、哈希MAP、JSON类型数据等&#xff0c;因此用户可以将很多常用数据库文件直接导入Tableau Deskt…