React 基础笔记 02

193 阅读5分钟

React 基础笔记 02

组件的数据挂载方式

1. 状态

状态就是组件描述某种显示情况的数据,由组件自己设置和更改,也就是说由组件自己维护,使用状态 的目的就是为了在不同的状态下使组件的显示不同(自己管理)

  1. 定义state
import React, { Component } from 'react';

class Test extends Component {
    state = {
        name: 'smiling' // 通过自定义变量 state
        }        
    render() {
        return (
            <div>
                <h1>第一种定义:{this.state.name}</h1>
            </div>
        );
    }
}

export default Test;
import React, { Component } from 'react';

class Test extends Component {

    constructor(){
        super()
        this.state = {
            name: 'smiling' // 通过构造器
        }
    }       
    render() {
        return (
            <div>
                <h1>第二种定义:{this.state.name}</h1>
            </div>
        );
    }
}

export default Test;
  1. setState

    this.state 是纯 js 对象,在 vue 中,data 属性是利用 Object.defineProperty 处理过的,更改 data 的数据的时候会触发数据的 getter 和 setter ,但是 React 中没有做这样的处理,如果直接更改的话, react是无法得知的,所以需要使用特殊的更改状态的方法 setState

    • setState 有两个参数

    第一个参数可以是对象,也可以是方法return一个对象,我们把这个参数叫做 updater

import React, { Component } from 'react';

class Test extends Component {
    constructor(){
        super()
        this.state = {
            name: 'smiling'
        }
    }
    handClick = () => {
        // 参数是对象
        this.setState({
            name: 'ling.wang'
        })
    }
    render() {
        return (
            <div>
                <h1>姓名:{this.state.name}</h1>
                <button onClick={this.handClick}>切换</button>
            </div>
        );
    }
}

export default Test;
import React, { Component } from 'react';

class Test extends Component {
    constructor(){
        super()
        this.state = {
            name: 'smiling'
        }
    }
    handClick = () => {
        // 参数是函数
        this.setState((prevState, props) => { 
            console.log(prevState, props)
            return {
                name: 'ling.wang'
            }
            }, () => {
            console.log('回调里的',this.state.name)
            })
            console.log('setState外部的',this.state.name)
    }
    render() {
        return (
            <div>
                <h1>姓名:{this.state.name}</h1>
                <button onClick={this.handClick}>切换</button>
            </div>
        );
    }
}

export default Test;

参数是函数的执行结果:

image.png

2. 属性 props

props 是正常是外部传入的,组件内部也可以通过一些方式来初始化的设置,属性不能被组件自己更 改,但是你可以通过父组件主动重新渲染的方式来传入新的 props

之前的组件代码里面有 props 的简单使用,总的来说,在使用一个组件的时候,可以把参数放在标签的属性当中,所有的属性都会作为组件 props 对象的键值。通过箭头函数创建的组件,需要通过函数的 参数来接收 props :

  • 在组件上通过key=value 写属性,通过this.props获取属性,这样组件的可复用性提高了。
  • 注意在传参数时候,如果写成isShow="true" 那么这是一个字符串 如果写成isShow={true} 这个 是布尔值
  • {...对象} 展开赋值
  • 默认属性值
  1. 属性验证
import React, { Component } from 'react';
import propsTypes from 'prop-types' // 引入检查类型

class Test extends Component {
    static propTypes = { title:propsTypes.string } // 属性验证
    render() {
        return (
            <div>
               <h1>{title}</h1>
            </div>
        );
    }
}

export default Test;

  1. 默认属性
import React, { Component } from 'react';
import propsTypes from 'prop-types' // 引入检查类型

class Test extends Component {
    static defaultProps = { show:true } // 默认属性
    render() {
        return (
            <div>
               <h1>{title}</h1>
            </div>
        );
    }
}

export default Test;

3. 属性VS状态

相似点:都是纯js对象,都会触发render更新,都具有确定性(状态/属性相同,结果相同)

不同点:

  1. 属性能从父组件获取,状态不能从父组件获取
  2. 属性可以由父组件修改,状态不能由父组件修改
  3. 属性能在内部设置默认值,状态也可以,设置方式不一样
  4. 属性不在组件内部修改,状态要在组件内部修改
  5. 属性能设置子组件初始值,状态不可以设置子组件初始值
  6. 属性可以修改子组件的值,状态不可以,state 的主要作用是用于组件保存、控制、修改自己的可变状态。

state 在组件内部初始化,可以被组件自身修改,而外部不能访问也不能修改。可以认为 state 是一个局部的、只能被组件自身控制的数据源。 state 中状态可以通过 this.setState 方法进行更新,setState 会导致组件的重新渲染。

props 的主要作用是让使用该组件的父组件可以传入参数来配置该组件。它是外部传进来的配置参数,组件内部无法控制也无法修改。除非外部组件主动传入新的 props ,否则组件的 props 永远保持不变。

没有 state 的组件叫无状态组件(stateless component),设置了 state 的叫做有状态组件 (stateful component)。因为状态会带来管理的复杂性,尽量多地写无状态组件,尽量少地写有状态的组件。这样会降低代码维护的难度,也会在一定程度上增强组件的可复用性。

数据渲染

  1. 条件渲染
<div>{show ? '显示' : '隐藏'}</div>
  1. 列表渲染
var list = ['1','2','3']

<div>
    <li key={index}>{list}</li>
</div>

React的高效依赖于所谓的 Virtual-DOM,尽量不碰 DOM。对于列表元素来说会有一个问题:元素可能 会在一个列表中改变位置。要实现这个操作,只需要交换一下 DOM 位置就行了,但是 React 并不知道 其实我们只是改变了元素的位置,所以它会重新渲染后面两个元素(再执行 Virtual-DOM ),这样会大 大增加 DOM 操作。但如果给每个元素加上唯一的标识,React 就可以知道这两个元素只是交换了位 置,这个标识就是 key ,这个 key 必须是每个元素唯一的标识

一个简易的 todolist 案例:

import React, { Component } from 'react';

class Test extends Component {
    constructor(){
        super()
        this.state = {
            list: [
                {
                    text:'吃饭'
                },
                {
                    text:'睡觉'
                }
            ]
        }
    }

    refInput = React.createRef()

    handleAdd = () => {
        this.state.list.push({ text:this.refInput.current.value})
        this.setState({
            list:this.state.list
        })

        this.refInput.current.value = '' // 清空输入框
    }

    handleDel = (index) => {
        this.state.list.splice(index,1)
        this.setState({
            list:this.state.list
        })
    }

    render() {
        return (
            <div>
                <input ref={this.refInput}/>
                <button onClick={this.handleAdd}>添加</button>
                <ul>
                    {  
                        this.state.list.map((item,index)=>{
                            return <li key={index}>{item.text} 
                                <button onClick={() => this.handleDel(index)}>删除</button>
                            </li> 
                        })
                    }

                    {
                        this.state.list.length === 0 ? <h3 style={{color: 'red'}}>暂无数据</h3> : null
                    }
                </ul>
            </div>
        );
    }
}

export default Test;

  • @Title: React 基础笔记 02
  • @Content: React
  • @Autor: ling.wang
  • @StudyDate: 2022-04-05、2022-04-10
  • @WritingDate: 2022-04-05、2022-04-10