重学React基础知识整理(二)

本文详细介绍了React的基本概念,包括React组件的创建、jsx语法、组件的渲染规则以及状态管理和更新。通过实例展示了如何创建一个React组件,如何修改样式,以及如何使用setState进行状态变更。还探讨了setState的异步行为及其注意事项。文章旨在帮助读者深入理解React的组件化思想和状态管理机制。
摘要由CSDN通过智能技术生成

React是什么?

官方文档上解释是:React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。

一个简单的react组件是怎么样的?

在上一节我们创造一个react项目,现在我们创建的一个叫做HelloWorld.js的react组件,在App.js里引入该组件就行,引入代码为使用es6的import去引入,具体代码如下:

import HelloWorld from './components/HelloWorld
具体解释是import是es6语法,HelloWorld被引入的组件名,'./components/HelloWorld’在项目中组件的地址。

下面是我们创建的一个叫做HelloWorld.js的react组件。代码1

import React, { Component } from 'react'; // 引入react和react的Component

export default class HellWorld extends Component { // 输出一个默认名字为HellWorld的类并继承了react的Component类
  render() {
    return (
      <div>HellWorld</div>
    )
  }
}

上面代码其实代价于下面代码:
代码2

import React, { Component } from 'react'; // 引入react和react的Component

class HellWorld extends Component { //写一个HellWorld的类并继承了react的Component类
  render() {
    return (
      <div>HellWorld</div>
    )
  }
}
export default HellWorld // 输出一个默认名字为HellWorld的类

由此可清晰可见一个react的组件有三部分组成。一、引入react;二、书写一个类并继承react的Component类;三、输出默认类名。
其中二书写一个类,里面有一个render函数,这个函数里面可以写HTML的dom结构和js这里叫做jsx语法。
jsx的原理,是将dom解析为一个dom对象,上面代码解析后会变成如下所示代码:
代码3

import React, { Component } from 'react'

export default class HellWorld extends Component {
  render() {
    return (
    //   <div>HellWorld</div>
    React.createElement(
        "div",
        null,//这里写一个该dom包含的属性对象,比如{className:'bg-red',id:'app'},这表示这个div有class类为bg-red,id为app
        "HellWorld"
    )
    )
  }
}

也就是说代码1和代码2、代码3渲染出来的效果是完全一样的。

重点:

1)render函数里面必须是一个dom标签包裹住其他dom标签,也就是说最外层的dom标签不能有兄弟dom.如果写两个并列的dom编辑器和浏览器都会报错如下图所示:

image.png

image.png
2)render函数里return返回里要写js需要{}包裹,代码如下:

import React, { Component } from 'react'

import './index.css'

export default class HelloWorld extends Component {
  render() {
    let a= 'HelloWorld---a'
    return (
      <div>{a}</div>
    )
  }
}

运行结果如下:

image.png

react中如何修改样式

修改样式有如下两种。一种是设置style,style里传递的是一个对象;一种是设置className(注意不是class,设置成class会报错),引入具有相应class类的css文件即可。具体表现形式和代码如下:

import React, { Component } from 'react'

import './index.css' // 引入css文件

export default class HelloWorld extends Component {
  render() {
    let a= 'HelloWorld---a'
    let stylea = {color:'blue'}
    return (
        <div>
            {/* 1、直接以对象的形式给style */}
            <div style={{color:'red'}}>HelloWorld</div>
            {/*2、 以对象变量的形式给style */}
            <div style={stylea}>HelloWorld</div>
            {/* 3、直接写class的css类名 */}
            <div className='bg-red'>{a}</div>
            {/* 4、利用js的正则表达式动态的写class的css类名 */}
            <div className={1+1>0?'bg-blue':''}>HelloWorld----b</div>
        </div>
      
    )
  }
}

在项目中利用js的正则表达式去动态的改变项目里组件的样式是非常常见的。

react中状态怎么写?

第一种是直接在render外面写一个state对象,具体示例如下所示:

import React, { Component } from 'react'

export default class HelloWroldState extends Component {
  state={
    hello:'HelloWroldState-----hello'
  }
  render() {
    return (
      <div>
        <div>HelloWroldState</div>
        <div>{this.state.hello}</div>
      </div>
    )
  }
}

代码运行结果如下图所示:

image.png

第二种写法就是在render外面写一个constructor构造函数,请千万注意里面要加个super()不然会报错,具体代码如下:

import React, { Component } from 'react'

export default class HelloWroldState extends Component {
  // state={
  //   hello:'HelloWroldState-----hello'
  // }
  constructor(){
    super()
    this.state={
      helloBlue:'HelloWroldState-----helloBlue'
    }
  }
  render() {
    return (
      <div>
        <div>HelloWroldState</div>
        {/* <div style={{color:'red'}}>{this.state.hello}</div> */}
        <div style={{backgroundColor:'blue'}}>{this.state.helloBlue}</div>
      </div>
    )
  }
}


image.png

一般正式项目开发时一般以第二种写法为主,可是做为小垃圾的我们也得认识人家第一种写法,不能说别人写错了,不然就有点贻笑大方了。

**注意:**这里的this是指向class组件。

React的state怎么变化?

做为一个js老手顾名思义一个js对象的值改变,我们传统的方法直接赋值改变就行了,比如:

let object={a:'3',b:'4'};
object.a = 8
console.log(object) // {a:8,b:4}

直接就修改了,但是React的state却是不能这样变化,它依赖于React的特性,需要调用setState方法。具体代码如下:

import React, { Component } from 'react'

export default class HelloWroldState extends Component {
  // state={
  //   hello:'HelloWroldState-----hello'
  // }
  constructor(){
    super()
    this.state={
      helloBlue:'HelloWroldState-----helloBlue',
      num:0
    }
  }
  render() {
    return (
      <div>
        <div>HelloWroldState</div>
        {/* <div style={{color:'red'}}>{this.state.hello}</div> */}
        <div style={{backgroundColor:'blue'}}>{this.state.helloBlue}</div>
        <h1>{this.state.num}</h1>
        <button onClick={this.click}>加一</button>
      </div>
    )
  }
  click=()=>{
    this.setState({
      num:this.state.num+1
    })
  }
}

结果如下所示:
image.png

setState方法的注意事项

1、在同步方法中,setState方法是合并执行的,即它只会运行一次,而且还是异步的,异步更新状态,异步更新真实dom。具体看代码,代码如下:

import React, { Component } from 'react'

export default class HelloWroldState extends Component {
  // state={
  //   hello:'HelloWroldState-----hello'
  // }
  constructor(){
    super()
    this.state={
      helloBlue:'HelloWroldState-----helloBlue',
      num:0
    }
  }
  render() {
    return (
      <div>
        <div>HelloWroldState</div>
        {/* <div style={{color:'red'}}>{this.state.hello}</div> */}
        <div style={{backgroundColor:'blue'}}>{this.state.helloBlue}</div>
        <h1>{this.state.num}</h1>
        <button onClick={this.click}>加一</button>
      </div>
    )
  }
  click=()=>{
    this.setState({
      num:this.state.num+1
    })
    console.log('log1',this.state.num)
    this.setState({
      num:this.state.num+1
    })
    console.log('log2',this.state.num)
    this.setState({
      num:this.state.num+1
    })
    console.log('log3',this.state.num)
  }
}

结果如下图所示:

image.png
由上图可以看出来num从0变到1,说明click方法里面的setState方法都合并了只执行了一次,但是三个console打印里面都是0,说明setState是异步的nun打印出来没变,但是页面上是有变化的说明setState是起了作用的。

2、在原生方法和setTimeout异步方法中,setState同步执行,状态同步更新,dom同步渲染.
3、setState的第二个参数是回调函数,可以取到变化值。

import React, { Component } from 'react'

export default class HelloWroldState extends Component {
  // state={
  //   hello:'HelloWroldState-----hello'
  // }
  constructor(){
    super()
    this.state={
      helloBlue:'HelloWroldState-----helloBlue',
      num:0
    }
  }
  render() {
    return (
      <div>
        <div>HelloWroldState</div>
        {/* <div style={{color:'red'}}>{this.state.hello}</div> */}
        <div style={{backgroundColor:'blue'}}>{this.state.helloBlue}</div>
        <h1>{this.state.num}</h1>
        <button onClick={this.click}>加一</button>
      </div>
    )
  }
  click=()=>{
      this.setState({
        num:this.state.num+1
      },()=>{
        console.log('log000',this.state.num)
      })
      this.setState({
        num:this.state.num+1
      },()=>{
        console.log('log001',this.state.num)
      })
      this.setState({
        num:this.state.num+1
      },()=>{
        console.log('log002',this.state.num)
      })
      console.log('log1',this.state.num)
      this.setState({
        num:this.state.num+1
      })
      console.log('log2',this.state.num)
      this.setState({
        num:this.state.num+1
      })
      console.log('log3',this.state.num)
    }
    
}

执行结果
image.png

4、setState函数调用一次会引发render函数重新渲染。没有state的变化则render不会重新渲染。这点在于组件里数据渲染变化的应用中很是重要
5、react中要特别注意this的指向问题,所以为了规避这个问题,一般都会选择箭头函数,因为箭头函数的this是指向他的非箭头函数的方法的,所以会一直指向到class,从而不会发生错误。

闲话

隔了很久重新捡起,感觉还是有点小吃力,祝大家温故而知新。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值