react学习

一、基础准备

二、代码练习

使用vscode

  1. 创建虚拟DOM
  2. 渲染虚拟DOM到页面
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>hello_react</title>
</head>
<body>
	<!-- 准备一个“容器” -->
	<div id="test"></div>

	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<!-- 引入babel,用于将jsx转为js -->
	<script type="text/javascript" src="../js/babel.min.js"></script>

	<script type="text/babel" > /* 一定要写babel */
		//1.创建虚拟DOM
		const VDOM = <h1>Hello,React</h1> /* 一定不要写引号,因为不是字符串 */
		//2.渲染虚拟DOM到页面
		ReactDOM.render(VDOM,document.getElementById('test'))
	</script>
</body>

运行结果

 出现这个警告是因为此时写的不是js,是jsx,并不标准,需要babel翻译成js,当代码量大了之后,就会出现问题,解决办法是用开发者工具开发。

注:此时无需处理此告警

虚拟DOM两种创建方式

  1. 使用jsx创建
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>使用jsx创建虚拟DOM</title>
</head>
<body>
	<!-- 准备好容器 -->
	<div id="test"></div>

	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<!-- 引入babel,用于将jsx转为js -->
	<script type="text/javascript" src="../js/babel.min.js"></script>

	<script type="text/babel" >
		//1.创建虚拟DOM
		const VDOM = (  /* 不要写引号,因为不是字符串 */
			<h1 id="title">
				<span>Hello,React</span>
			</h1>
		)
		//2.渲染虚拟DOM到页面
		ReactDOM.render(VDOM,document.getElementById('test'))
	</script>
</body>
</html>
  1. 使用js创建
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>使用js创建虚拟DOM</title>
</head>
<body>
	<!-- 准备好一个“容器” -->
	<div id="test"></div>

	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/react-dom.development.js"></script>

	<script type="text/javascript" > 
		//1.创建虚拟DOM
		const VDOM = React.createElement('h1',{id:'title'},React.createElement('span',{},'Hello!'))
		//2.渲染虚拟DOM到页面
		ReactDOM.render(VDOM,document.getElementById('test'))
	</script>
</body>
</html>

总结:jsx创建虚拟DOM更加方便

虚拟DOM与真实DOM

  1. 本质是Object类型的对象(一般对象)。
  2. 虚拟DOM属性少,真实DOM属性多,因为虚拟DOM是React内部在用,无需真实DOM上那么多的属性。
  3. 虚拟DOM最终会被React转化为真实DOM,呈现在页面上。

三、JSX语法规则

jsx是js的扩展语法

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>jsx语法规则</title>
	<style>
		.title{
			background-color: orange;
			width: 200px;
		}
	</style>
</head>
<body>
	<!-- “容器” -->
	<div id="test"></div>

	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<!-- 引入babel,用于将jsx转为js -->
	<script type="text/javascript" src="../js/babel.min.js"></script>

	<script type="text/babel" >
		const myId = 'test'
		const myData = 'HeLlo'

		//1.创建虚拟DOM
		const VDOM = (
            // 只有一个根标签
			<div>
				<h2 className="title" id={myId.toLowerCase()}>
					<span style={{color:'white',fontSize:'24px'}}>{myData.toLowerCase()}</span>
				</h2>
				<h2 className="title" id={myId.toUpperCase()}>
					<span style={{color:'red',fontSize:'28px'}}>{myData.toLowerCase()}</span>
				</h2>
				<input type="text"/>
			</div>
		)
		//2.渲染虚拟DOM到页面
		ReactDOM.render(VDOM,document.getElementById('test'))

		/* 
				jsx语法规则:
						1.定义虚拟DOM时,不要写引号。
						2.标签中混入JS表达式时要用{}。
						3.样式的类名指定不要用class,要用className。
						4.内联样式,要用style={{key:value}}的形式去写。
						5.只有一个根标签
						6.标签必须闭合
						7.标签首字母
							(1).若小写字母开头,则将该标签转为html中同名元素,若html中无该标签对应的同名元素,则报错。
							(2).若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错。

		 */
	</script>
</body>
</html>

区分:【js语句(代码)】与【js表达式】

                    1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方

                                下面这些都是表达式:

                                        (1). a

                                        (2). a+b

                                        (3). demo(6)

                                        (4). arr.map()

                                        (5). function add() {}

                    2.语句(代码):

                                下面这些都是语句(代码):

                                        (1).if(){}

                                        (2).for(){}

                                        (3).switch(){case:xxxx}

四、组件状态

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

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

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

状态初始化

状态的变化

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

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

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

组件中的数据

  1. props:该数据是由组件的使用者传递的数据,所有权不属于组件自身,因此组件无法改变该数组
  2. state:该数组是由组件自身创建的,所有权属于组件自身,因此组件有权改变该数据
//计时器,用作倒计时
import React, { Component } from 'react'

export default class Tick extends Component {
    //初始化状态,JS Next 语法,目前处于实验阶段
    state = {
        left: this.props.number,
        n: 123
    }

    constructor(props) {
        super(props);
        //初始化状态
        // this.state = {
        //     left: this.props.number
        // };
        this.timer = setInterval(() => {
            this.setState({
                left: this.state.left - 1
            }); //重新设置状态,触发自动的重新渲染
            if (this.state.left === 0) {
                //停止计时器
                clearInterval(this.timer);
            }
        }, 1000);
    }

    render() {
        return (
            <>
                <h1>
                    倒计时剩余时间:{this.state.left}
                </h1>
                <p>
                    {this.state.n}
                </p>
            </>
        )
    }
}

五、组件事件

在React中,组件的事件,本质上就是一个属性

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

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

使用bind函数,绑定this

import React, { Component } from 'react'
import Tick from "./Tick"

export default class TickControl extends Component {

    state = {
        isOver: false //倒计时是否完成
    }

    // 结果:handleClick不在原型上,而在对象上
    handleClick = () => {
        console.log(this)
        console.log("点击了")
    }

    handleOver = () => {
        this.setState({
            isOver: true
        })
    }

    render() {
        let status = "正在倒计时";
        if (this.state.isOver) {
            status = "倒计时完成";
        }
        return (
            <div>
                <Tick
                    onClick={this.handleClick.bind(this)}
                    onOver={this.handleClick.bind(this)}
                    number={10} />
                <h2>
                    {status}
                </h2>
            </div>
        )
    }
}

使用箭头函数

import React, { Component } from 'react'
import Tick from "./Tick"

export default class TickControl extends Component {

    state = {
        isOver: false //倒计时是否完成
    }

    // 结果:handleClick不在原型上,而在对象上
    handleClick = () => {
        console.log(this)
        console.log("点击了")
    }

    handleOver = () => {
        this.setState({
            isOver: true
        })
    }

    render() {
        let status = "正在倒计时";
        if (this.state.isOver) {
            status = "倒计时完成";
        }
        return (
            <div>
                <Tick
                    onClick={this.handleClick}
                    onOver={this.handleClick}
                    number={10} />
                <h2>
                    {status}
                </h2>
            </div>
        )
    }
}

六、深入认识setState

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

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

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

最佳实践:

  1. 把所有的setState当作是异步的
  2. 永远不要信任setState调用之后的状态
  3. 如果要使用改变之后的状态,需要使用回调函数(setState的第二个参数)
  4. 如果新的状态要根据之前的状态进行运算,使用函数的方式改变状态(setState的第一个函数)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值