04 组件学习2

组件状态

在react hook出现之前,函数式组件是没有自己的状态的,所以我们统一通过类组件类讲解步骤:

初始化状态->读取状态->修改状态->影响视图

// 组件状态 类组件为演示
import React from "react"
class HelloTest extends React.Component {
  // 定义组件状态
  state = {
    // 定义属性
    name: 'seek0608',
    age: 18
  }
  changeName = () => {
    // 修改state中的状态name
    // 注意:不可以直接复制修改,必须通过一个方法setState
    //this.state.name = "test"  ×
    console.log(123)
    this.setState({
      name: 'demo'
    })
  }
  render () {
    return (
      <div>
        this is HelloTest
        <div>
          <h2>name: {this.state.name}</h2>
          <button onClick={this.changeName}>修改name</button>
        </div>
      </div>
    )
  }
}

注意:

react编写组件就是编写原生js类或者函数、

定义状态必须通过state实例属性的方式提供一个对象,名称固定为state

修改state中 的任何属性,不能通过直接复制,必须走setState方法,这个方法来自于继承React.Component得到

this关键词很容易出现指向错误问题,请注意规范

this问题

由于this的指向问题,三种写法,但是实际中只需要写第一种即可

class Test extends React.Component {
  // 定义组件状态
  state = {
    // 定义属性
    counter: 1,
  }
  changeName = () => {
    this.setState({
      counter: this.state.counter + 1
    })
  }
  render () {
    return (
      <div>
        <button onClick={this.changeName}>{this.state.counter}click</button>
      </div>
    )
  }
}

class Test2 extends React.Component {
  // 定义组件状态
  state = {
    // 定义属性
    counter: 1,
  }
  changeName () {
    this.setState({
      counter: this.state.counter + 1
    })
  }
  render () {
    return (
      <div>
        <button onClick={() => this.changeName()}>{this.state.counter}click</button>
      </div>
    )
  }
}

class Test3 extends React.Component {
  constructor() {
    super()
    this.changeName = this.changeName.bind(this)
  }
  // 定义组件状态
  state = {
    // 定义属性
    counter: 1,
  }
  changeName () {
    this.setState({
      counter: this.state.counter + 1
    })
  }
  render () {
    return (
      <div>
        <button onClick={this.changeName}>{this.state.counter}click</button>
      </div>
    )
  }
}

react的状态不可变

永远不要直接修改状态的值,而是基于当前状态创建新的状态值

import React from "react"
class Test extends React.Component {
  state = {
    counter: 1,
    list: [1, 2, 4],
    person: {
      name: 'seek',
      agw: 18
    }
  }

  changeCounter = () => {
    // 错误写法,是直接修改
    this.state.counter++
    ++this.state.counter
    this.state.counter += 1

    // 正确写法
    this.setState({
      counter: this.state.counter + 1
    })
  }
  changeList = () => {
    // 错误写法,是直接修改
    this.state.list.push(3)
    this.state.list.pop()

    // 正确写法
    this.setState({
      list: [...this.state.list, 3]
    })
  }
  changePopList = () => {
    this.setState({
      list: this.state.list.filter(item => item !== 2)
    })
  }
  changePerson = () => {
    // 错误写法,是直接修改
    this.state.person.name = "seek0608"
    this.setState({
      person: {
        ...this.state.person,
        name: 'rose'
      }
    })
  }
  render () {
    return (
      <>
        <div>{this.state.counter}</div>
        <ul>
          {this.state.list.map(item => <li key={item}>{item}</li>)}
        </ul>
        <div>{this.state.person.name}</div>
        <button onClick={this.changeCounter}>{this.state.counter}click</button>
        <button onClick={this.changeList}>{this.state.counter}click</button>
        <button onClick={this.changePopList}>{this.state.counter}click</button>
        <button onClick={this.changePerson}>{this.state.counter}click</button>
      </>
    )
  }
}



function App () {
  return (
    <div className="App">
      <Test />
    </div>
  )
}

export default App

表单处理——受控组件

例如:input框自己状态被react组件的状态控制

react组件的状态的地方是在state中,input表单元素也有自己的状态是在value中,react将state与表单元素的值绑定在一起,由state的值来控制表单元素的值,从而保证单一数据源特性

实现步骤:

  • 在组件的state中声明一个组件的状态数据
  • 将状态数据设置为input标签元素的value属性的值
  • 为input添加change事件,在事件处理程序中,通过事件对象e获取到当前文本框的值(即用户当前输入的值
  • 调用setState方法,将文本框的值作为state状态的最新值
class Counter extends React.Component {
  state = {
    counter: 'this is message',
  }
  changeCounter = (e) => {
    this.setState({
      counter: e.target.value
    })
  }
  render () {
    return (
      <>
        <div>{this.state.counter}</div>
        <input type='text' value={this.state.counter} onChange={this.changeCounter} />
      </>
    )
  }
}

表单处理——非受控组件

非受控组件就是通过手动操作dom的方式获取文本框的值,文本框的状态不受react组件的state中的状态控制,直接通过原生dom获取输入框的值

实现步骤

  1. 导入createRef 函数
  2. 调用createRef函数,创建一个ref对象,存储到名为msgRef的实例属性中
  3. 为input添加ref属性,值为msgRef
  4. 在按钮的事件处理程序中,通过msgRef.current即可拿到input对应的dom元素,而其中msgRef.current.value拿到的就是文本框的值
import React, { createRef } from "react"
class InputComponent extends React.Component {
  // 这个实例属性是可以自定义的,语义化即可
  msgRef = createRef()
  state = {
    value: ""
  }
  getInputValue = () => {
    this.setState({
      value: this.msgRef.current.value
    })
  }
  // UI结构
  render () {
    return (
      <>
        <input type='text' ref={this.msgRef} />
        <h1>{this.state.value}</h1>
        <button onClick={this.getInputValue}>点击获取输入框的值</button>
      </>
    )
  }
}

使用ref获取绑定,并通过如下方式获取value

this.msgRef.current.value

this.msgRef.current表示原生的dom元素,然后通过value获取

猜你喜欢

转载自blog.csdn.net/qq_39225271/article/details/127167006