1

props

props是外部传入的,组件内部也可以进行一些初始化的设置,属性不能在组件内部进行修改,但是可以通过父组件主动重新渲染的方式来传入新的props。
通过props进行传值:

// 子组件是类组件
import React, { Component,Fragment } from 'react
export default class Child extends Component {
    render() {
        return (
            <>
                <h2>{this.props.title}</h2>
            </>
        )
    }
}
// 子组件是函数式组件
export default function Child(props){
    return (
        <h1>
            {props.title}
        </h1>
    )
}
// 父组件
import React,{Component} from 'react'
// 引入子组件
import Child from './Child'

export default class Parent extends Component {
    render(){
        return (
            <>
                <Child title="lilan"></Child>
            </>
        )
    }
}

当没有传参或者获取的时候没有该属性的时候,获取结果是undefined

设置组件的默认props

  1. 类组件

    class Child extends Component {
      // 使用类创建的组件,直接在这里写static方法,创建defaultProps
      static defaultProps = {
        name: 'React'
      }
      render () {
        return (
            <h1>欢迎进入{this.props.name}的世界</h1>
        )
      }
    }
  2. 函数式组件

    const Child = (props) => {
      return (
        <p>{props.name}是一个构建UI的库</p>
      )
    }
    
    // 使用箭头函数创建的组件,需要在这个组件上直接写defaultProps属性
    Child.defaultProps = {
      name: 'React.js'
    }

props.children

上面的属性props的值是一个对象,对象中包含一个children属性,children属性的值是一个数组,数组中包含使用该组件时包含在该组件内的元素。

// 子组件
export default class Child extends Component {
    render() {
        return (
            <h1>欢迎进入{this.props.children}的世界</h1>
            
        )
    }
    // 这个先不用管,只要知道在这个函数内可以也获取到props即可
    componentDidMount(){
        console.log(this.props)
        console.log(this.props.chidren)
    }
}
// 父组件
export default class Parent extends Component {
    render() {
        return (
            <Fragment>
                <Child title="todo">
                    <i>React</i>
                    <p>lilan</p>
                </Child>
            </Fragment>
        )
    }  
}

打印结果
image
children数组中的每一个元素都是包含在组件内的节点

使用prop-type检查props

React其实是为了构建大型应用程序而生, 在一个大型应用中,根本不知道别人使用你写的组件的时候会传入什么样的参数,有可能会造成应用程序运行不了,但是不报错。为了解决这个问题,React提供了一种机制,让写组件的人可以给组件的props设定参数检查,需要安装和使用prop-types

npm i prop-types -S

状态 state

状态就是组件描述某种显示情况的数据,由组件自己设置和更改,也就是说由组件自己维护,使用状态的目的就是为了在不同状态下使组件的显示不一样。一般情况下,函数式组件是无状态组件,状态只有类组件才有。

定义state

  1. 第一种方式

    import React, { Component } from 'react'
    
    export default class State extends Component {
      state = {
        name: 'React',
      }
      render () {
        return (
          <div>
            <h1>欢迎来到{this.state.name}的世界</h1>
          </div>
        )
      }
    }
  2. 第二种方式(推荐)

    export default class State extends Component {
        constructor(){
            super()
            this.state = {
                name:'React'
            }
        }
        render() {
            return (
                <div>
                    <h1>欢迎来到{this.state.name}的世界</h1>
                </div>
            )
        }
    }

setState

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

上面的demo中,name存放在梳理的state对象当中,组件的render函数内,会依据state中的数据进行显示。下面给h1添加事件监听。

import React, { Component } from 'react'
export default class State extends Component {
    constructor(){
        super()
        this.state = {
            name:'React'
        }
    }

    handleClick = () => {
        this.setState({
            name:"VUE"
        })
    }
    render() {
        return (
            <div>
                <h1 onClick={this.handleClick}>欢迎来到{this.state.name}的世界</h1>
            </div>
        )
    }
}

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

  • 参数是对象
this.setState({
    name:"VUE"
})
  • 参数是方法
this.setState((prevState, props) => {
    return {
        name: "VUE"
    }
})

注意的是这个方法接收两个参数,第一个是上一次的state,第二个就是props,setState是异步的,所以想要获取到最新的state,是没有办法获取的,就有了第二个参数,这是一个可选的回调函数

this.setState((prevState, props) => {
    return {
        name: "VUE"
    }
}, () => {
    console.log("回调里面的state中的name:",this.state.name)
})
console.log("外部的state中的name:",this.state.name)

属性 VS 状态

  • 相同点:都是纯JS对象,都会触发render的更新,都具有确定性
  • 不同点:

    1. 属性能从父组件获取,状态不可以
    2. 属性可以由父组件修改,状态不可以
    3. 属性能在内部设置默认值,状态也可以
    4. 属性不能在组件内部修改,状态可以
    5. 属性能设置子组件初始值,状态不可以
    6. 属性可以修改子组件的值,状态不可以

上面的不同点其实就是车轱辘话,总结一下就是状态只能是组件自己改,但是属性是可以通过父组件控制的。

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

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


那小孩儿
1 声望1 粉丝