react有状态组件无状态组件和绑定this指向

1,855 阅读3分钟

整理react学习知识

一、有状态组件和无状态组件

数据就是状态(state),数据的变化就是状态的变化(setState())

有维护自己状态存储和变化机制的组件叫做有状态组件,没有的叫做无状态组件或UI组件

比如动态显示当前时间的需求,就是符合有状态组件的定义 在这里插入图片描述

在React中,类组件是有状态组件,函数组件是无状态组件

二、组件的state和setState

1. state的基本使用

state是数据的容器,用来存储组件内部(私有)的数据,私有的表现就是只能在组件内部使用

state在类组件的构造函数中初始化,值是对象,表示一个组件中可以有多个数据

state的使用,{this.state.time}

代码如下(示例):

class Timer extends React.Component {
  constructor() {
    super()
    // 初始化组件状态(state)
    this.state = {
      time: ’’
    }
  }
  render() {
    return (
      <div>当前时间是:{this.state.time}</div>
    )
  }
}

在构造函数中初始化 通过 this.state 来获取状态数据

2. setState() 修改状态

this.setState({ 要修改的数据 })

setState() 作用:1. 修改 state 2. 更新UI 注意:不要直接修改 state 中的值,这是错误的!!!

三、事件绑定 this 指向

1. 箭头函数

利用箭头函数自身不绑定this的特点 render() 方法中的 this 为组件实例,可以获取到 setState()

代码如下(示例):

class Timer extends React.Component {
  handleClick() {
    this.setState({ … })
  }
  render() {
    // 箭头函数中的this指向外部环境,此处为:render()方法
    return (
      <button onClick={() => this.handleClick()}></button>
    )
  }
}

2. Function.prototype.bind()

利用ES5中的bind方法,将事件处理程序中的this与组件实例绑定到一起

代码如下(示例):

class Timer extends React.Component {
  constructor(props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
  }
  // ...省略 handleClick
  render() {
    return (
      <button onClick={this.handleClick}></button>
    )
  }
}

3. class 的公有字段方法(推荐)

利用箭头函数形式的class实例方法 注意:该语法是实验性语法,但是,由于babel的存在可以直接使用

class Timer extends React.Component {
  handleClick = () => {
    this.setState({ … })
  }
  render() {
    return (
      <button onClick={this.handleClick}></button>
    )
  }
}

四、 表单处理

1. 受控组件

HTML 中的表单元素是可输入的,也就是有自己的可变状态 而,React 中可变状态通常保存在 state 中,并且只能通过 setState() 方法来修改

在这里插入图片描述 React将 state 与表单元素的value属性绑定到一起,由 state 的值来控制表单元素的值 受控组件:React 控制表单元素值 在这里插入图片描述

步骤: 在 state 中添加一个状态,作为表单元素value属性值(控制表单元素值的来源) 给表单元素绑定 onChange 事件,通过调用setState()改变state的值(控制表单元素值的变化)

state = { txt: ’’ }
<input type="text" value={this.state.txt}
  onChange={e => this.setState({ txt: e.target.value })}
/>

多表单元素优化步骤:

  • 给表单元素添加name属性,名称与 state 相同
  • 根据表单元素类型获取对应值
  • 在 change 事件处理程序中通过 [name] 来修改对应的state
<input
  type="text"
  name="txt"
  value={this.state.txt}
  onChange={this.handleForm}
/>

// 根据表单元素类型获取值
const value = target.type === 'checkbox' ? target.checked : target.value
// 根据name设置对应state
this.setState({
  [name]: value
})

2. 非受控组件(DOM方式)

  • 不受React中的state状态属性控制
  • 借助于 ref,使用原生 DOM 方式来获取表单元素值
  • ref 属性作用,获取DOM对象或者React组件

使用步骤: 调用 React.createRef() 方法创建一个 Refs 对象

constructor() {
  super()
  this.txtRef = React.createRef()
}

将创建好的 Refs 对象和表单元素关联

<input type="text" ref={this.txtRef} />

通过 Refs 对象的 .current 属性获取到文本框的值

console.log(this.txtRef.current.value)