react-Props与State

首先在这里引用 react 官网的几句话

React :元素构成组件,组件又构成应用。
React核心思想是组件化,其中 组件 通过属性(props) 和 状态(state)传递数据。

 State 与 Props 区别 

引用一句很精髓的概括:props 是组件对外的接口,state 是组件对内的接口 。这句话其实很好的解释了 state 与 Props 的区别。

Props属性:组件对外的接口,通过 Props 进行组件之间的数据传递

State状态:除了上层组件传递的 Props数据之外,组件内部也会存在独有数据,在组件内部根据不同的情况改变,从而维护改变组件状态

 

props

1、props是单向传递的,只能从父组件传递到子组件,和vue的数据传递类似。 

2、在子组件内部使用 父组件传递过来的 props数据时,需要使用 this.props.xxx 才能调用

3、组件内部的 props 只能读取,不能被更改。如果非要更改的话,可以让父组件传递一个事件,在子组件中调用事件的同时,将数据传递到父组件中

4、父组件向子组件中传递数据时,如果需要传递的数据很多,可以使用扩展运算符来便捷传递

井字棋案例中:

父组件 Game.js 调用了子组件 Board.js ,且传递了 当前 点击之后的单元格数据,也就是当前游戏进程。同时,也传递了一个 onClick 事件,没错,这个事件也被传递到子组件了。

<Board
  squares={current.squares}
  onClick={i => {
    this.handleClick(i);
  }}
/>

然后在子组件 Board.js 组件中 通过  this.props.xxx  获取父组件传递的数据,渲染单元格,而且,在点击单元格的时候,会触发父组件 传递的事件,也就是说,这个事件,实际上是在父组件内部触发的。

<Square
  key={i}
  value={this.props.squares[i]}
  onClick={() => this.props.onClick(i)}
/>

从这里就可以看到,父组件传递的数据,子组件需要使用 this.props.xxx 接收 。子组件要想改变props,可以通过 事件传递的方式。

 传递多个属性,如果我们在调用子组件时,向这样 通过 props 传递多个属性,无疑是很麻烦的,所以才有了下面的简便方法

import React from 'react';
import ReactDOM from 'react-dom';

class Me extends React.Component {
    render() {
        return <h1>{this.props.a} - {this.props.b} - {this.props.c}</h1>
    }
}

ReactDOM.render(
    // 向子组件内部 传递了多个数据,这样写会很麻烦
    <Me a="1" b="2" c="3" />,
    document.getElementById('root')
);

通过对象传递:通过 Props 传递一个对象给子组件,子组件也需要接收一个对象,从这个对象内部取值

import React from 'react';
import ReactDOM from 'react-dom';

class Me extends React.Component {
    render() {
        return <h1>{this.props.data.a} - {this.props.data.b} - {this.props.data.c}</h1>
    }
}

const sj = {
    a: '1',
    b: '2',
    c: '3'
};

ReactDOM.render(
    <Me data={sj}/>,
    document.getElementById('root')
);

通过扩展运算符传递一个对象:子组件接收的时候,可以直接使用 this.props.xxx 获取属性值

import React from 'react';
import ReactDOM from 'react-dom';

class Me extends React.Component {
    render() {
        return <h1>{this.props.a} - {this.props.b} - {this.props.c}</h1>
    }
}

const sj = {
    a: '1',
    b: '2',
    c: '3'
};

ReactDOM.render(
    // 通过扩展运算符传递一个对象
    <Me {...sj} />,
    document.getElementById('root')
);

总结:显然通过扩展运算符更方便,因为它即将数据包装成了一个我们常用的对象格式,而且还采用扩展运算符简化了赋值的书写 

 

State

官网中是这么说的:State 与 props 类似,但是 state 是私有的,并且完全受控于当前组件。 State是一个组件的UI数据模型,是组件渲染时的数据依据。

 

正确地使用 State

1、构造函数是唯一可以给 this.state 赋值的地方:

constructor(props) {
  super(props);
  this.state = {
    history: [{ squares: Array(9).fill(null) }],
    xIsNext: true,
    setNumber: 0,
    coordinate: [[0, 0]], //初始位置默认为坐标[0,0]
    isReverse: false
  };
}

 2、通过 setState() 来修改 state

直接修改 state 内部的属性,是不会生效的,这样并不会重新渲染组件

this.state.setNumber = 1111

而是需要通过 setState() 来修改数据

this.setState({
    setNumber : 1111
})

3、State 的更新是异步的 

当我的数据更新之后,我的视图层是不会立即更新的,而是会进入一个队列中,等到下次这个队列执行的时候在开始更新Dom,和vue类似。类似与vue的 nexttick

  • 调用setState后,setState会把要修改的状态放入一个队列中(因而 组件的state并不会立即改变)
  • State 的更新会被合并。调用 setState  多次修改同一个属性值的时候,会依次添加到队列中,且最后一次添加的会覆盖之前
  • 子组件接收到的 Props 可能是父组件 中的 State ,所以在父组件中改变 State之后,子组件中的 Props 数据,可能是不会立即更新的,所以 我们不能依靠 State 来去计算下一个组件的值

总结:this.props 和 this.state 可能是异步更新的,不能依赖他们的值计算下一个state(状态)

异步更新State

State的更新是异步的,和vue类似,但是vue中有 nexttick  可以触发更新,那么react中同样也可以异步的去更新Dom,这个同样还是需要用到 setState() 这个方法。

这个是官网的错误的例子,是一个计算器,数据相加之后,是不会立即更新当前值的

this.setState({
  counter: this.state.counter + this.props.increment,
});

要解决这个问题,可以让 setState() 接收一个函数 而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

//注意:下面这样是错的
this.setState((state, props) => { //没将{}用()括起来,所以会解析成代码块
  counter: state.counter + props.increment
});

当State变化,创建新的State

到了这一步,其实就比较好理解了,我们的数据如果是简单类型数据的话,直接赋值改变就可以,但是如果 是引用数据类型的话,就需要处理一下,我们需要创建一个副本,然后去操作这个副本,最后把处理过后的副本的值,重新通过 setState 去改变 State 

基本类型:直接赋值

//原state
this.state = {
  count: 0,
  title : 'React',
  success:false
}
//改变state
this.setState({
  count: 1,
  title: 'bty',
  success: true
})

引用类型:数组,此时不能直接赋值,而是需要得到一个新的数组副本,然后 通过 setState 重新赋值

在井字棋案例中,频繁使用了 副本数据,可以直接 先得到一个副本,然后通过数组方法  concat,splice、map,等处理数组之后返回一个新数组的方法

const history = this.state.history.slice();

let history = this.state.history;

注意:不要使用push、pop、shift、unshift、splice等方法修改数组类型的状态,因为这些方法都是在原数组的基础上修改,而concat、slice、filter会返回一个新的数组。

创建新的状态对象的关键是,避免使用会直接修改原对象的方法,而是使用可以返回一个新对象的方法。

数据是向下流动的 

每个组件的 State 数据,都可以当作 Props 中的数据,传递到子组件,而每个子组件内部,都可能存在自己私有的 State 数据,在子组件中,并不关心我得到的 Props 中的数据,是上级组件的 State 中的数据,还是Props数据(也就是更上一级的State数据)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: React中,propsstate是两种不同的数据类型。 propsproperties)是父组件传给子组件的数据,子组件只能读取这些数据,不能修改。 state(状态)是组件自身维护的数据,组件可以读取并修改这些数据。 简单来说,props是用来给组件传递参数,state是用来维护组件的状态。 ### 回答2: React 中的 propsstate 是两个非常重要的概念,它们有着不同的特点和作用。propsstate 的主要区别在于它们的来源、可变性和使用方式。 1. 来源 props 是组件之间传递数据的一种机制,是由父组件传递给子组件的。父组件可以通过 props 向子组件传递任意类型的数据,包括数字、字符串、对象、数组、甚至函数等。子组件不能通过 props 修改传递过来的数据,props 只读。 state 是组件内部自身管理的一种数据,每个组件都有自己的 state 状态。组件可以通过调用 setState 方法来修改自己的 state 数据。 2. 可变性 props 是只读的,是不可变的。它们被设计成只能由父组件传递给子组件,子组件不能修改 props。如果需要修改 props 中的值,只能在父组件中进行修改。 state 是可变的,它们被设计成可以由组件自身进行修改,组件内部调用 setState 方法来改变自己的状态。当修改 state 时,React 会自动重新渲染组件。 3. 使用方式 props 通常用于传递数据和回调函数,使不同组件之间可以进行通信和交互。父组件向子组件传递 props,子组件从 props 中获取数据进行渲染,同时通过回调函数进行数据的传递和事件的触发。 state 用于存储组件的状态和数据,可以更新组件的显示和行为。当组件的状态改变时,React 会自动重新渲染组件,并根据新的状态计算出新的渲染结果。 总之,propsstate 都是 React 中组件很重要的数据管理机制。它们各自的特点和使用方式也是不同的。props 主要用于组件之间的通信、数据传递和事件处理,state 则主要用于控制组件自身的状态和行为。需要根据实际情况和需求,选择合适的数据管理方式。 ### 回答3: React是一款非常强大的JavaScript库,被广泛用于基于组件的Web开发。在React开发中,propsstate是两个非常重要的概念,也是非常容易混淆的概念。 Props是组件之间传递数据的一种方式,通常被用于从父组件向子组件传递数据。Props是一个JavaScript对象,可以包含任何类型的数据,例如字符串、数组、对象等等。在组件内部,我们可以通过this.props来访问这些数据,并使用它们来渲染组件。 而StateReact组件中的另一个重要概念,表示组件内部的状态数据。在组件内部定义一个state对象,该对象内部包含了组件的状态数据。State是私有的,只能由组件本身进行修改,其他组件无法访问。当state数据发生变化时,React会自动重新渲染组件。 那么,propsstate有什么区别呢? 首先,props是外部数据,通常由父组件向子组件传递,而state是组件内部的状态数据,只能由组件内部进行修改。 其次,props是只读的,一旦被传递给子组件,就无法再被修改,而state是可以被修改的,并且当state发生变化时,React会自动重新渲染组件。 最后,props是使组件“可配置”的一种方式,允许我们根据不同的数据来渲染不同的组件。而state是使组件“可动态”的一种方式,允许我们根据组件内部的状态数据来动态更新组件。 在开发React组件时,我们通常会用props来传递外部数据,而state则用于存储组件内部的状态数据。这两种概念的合理应用,可以使组件更加灵活、易维护,并且更好地符合React的设计理念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值