React中的state,事件及SetSate

state的创建方法

类组件才是有状态的组件,如果是Arrow Function创建的组件,也叫做无状态组件(stateless compoment)

1.react里的第一种state定义

export default class App extends Component {
    state = {
        name: 'tianlanlan',
        age: 18,
        skills: [{
            id: 1,
            title: '吃饭'
          }, {
            id: 2,
            title: '睡觉'
          },{
            id: 3,
            title: '打豆豆'
          }]
    }
    
   render() {
    return (
      <Fragment>
        <dl>
          <dt>名字</dt>
          <dd>{this.state.name}</dd>
        </dl>
        <dl>
          <dt>年龄</dt>
          <dd>{this.state.age}</dd>
        </dl>
        <dl>
          <dt>技能</dt>
          {
            // 这里是语句,循环输出,在react里就是直接用map。而不是for
            // 而且这里不需要直接赋值,而是直接写map语句
            // 在React的循环里,必须要有一个key
            this.state.skills.map(item => {
              return (
                <dd key={item.id}>{item.title}</dd>
              )
            })
          }
        </dl>
      </Fragment>
    )
  }
}
复制代码

2.react里的第二种state定义(大多使用第二种)constructor只执行一次

constructor () {
    super();
    this.state = {
          name: 'tianlanlan',
          age: 18,
          skills: [{
            id: 1,
            title: '吃饭'
          }, {
            id: 2,
            title: '睡觉'
          },{
            id: 3,
            title: '打豆豆'
          }]
        }
    }
    render() {
    return (
      <Fragment>
        <dl>
          <dt>名字</dt>
          <dd>{this.state.name}</dd>
        </dl>
        <dl>
          <dt>年龄</dt>
          <dd>{this.state.age}</dd>
        </dl>
        <dl>
          <dt>技能</dt>
          {
            // 这里是语句,循环输出,在react里就是直接用map。而不是for
            // 而且这里不需要直接赋值,而是直接写map语句
            // 在React的循环里,必须要有一个key
            this.state.skills.map(item => {
              return (
                <dd key={item.id}>{item.title}</dd>
              )
            })
          }
        </dl>
      </Fragment>
    )
  }
复制代码

注意:

state的主要目的是为了把一些需要改变的数据管理起来,方便后期用数据决定显示的思想来进行重新渲染

事件绑定

1.箭头函数

定义一个事件,把一个箭头函数赋值给一个变量,在调用的时候,就用this.handleAgeAdd来进行调用

(1) 在react里不能!不能!不能!直接修改state,这样只是值更改了,不会触发render()

  handleAgeAdd = ()=> {
    this.state.age++
    console.log(this.state.age)
  }
复制代码

注意:

React不允许直接修改state,需要调用setState的方法来进行修改,每一次的state修改会直接反映到UI界面上

(2)如果需要更新state,必须!必须!必须!调用setState方法

handleAgeAdd = ()=> {
    this.setState({
      // 这里不能用++
      age: this.state.age + 1
    })
    console.log(this.state.age)
  }
复制代码

2.不是箭头函数

(1)setState的第一个参数,可以是一个对象

handleAgeAdd () {
    this.setState({
      age: this.state.age + 1
    }, () => {
      // 如果要获取到最新的state,需要在setState的第二个回调函数里去获取
      console.log('回调函数打印:', this.state.age)
    })
    // 这里永远打印出来的是上一次的state,而不是setState之后的,因为setState是异步的
    console.log('外面打印:', this.state.age)
  }
复制代码

注意:

如果要获取到最新的state,需要在setState的第二个回调函数里去获取

setState外面打印出来的是上一次的state,而不是setState之后的,因为setState是异步的

(2)setState的第一个参数,也可以是一个方法,但是,这个方法里必须要return一个对象

handleAgeAdd () {
    // 这个方法里的第一个参数,特别有用,是上一次的state
    this.setState((prevState) => {
      console.log(prevState)
      return {
        age: prevState.age + 1
      }
    })
  }
复制代码

注意:

// 如果是箭头函数,直接调用方法
<button onClick={this.handleAgeAdd}>增加一岁</button>
复制代码
// 如果不是箭头函数, 需要bind(this)
// 不推荐在render方法里bind(this),因为render方法会随着状态的更改,多次执行
<button onClick={this.handleAgeAdd.bind(this)}>增加一岁</button>
复制代码
// 如果不是箭头函数定义的方法,推荐在constructor这里进行bind(因为constructor只执行一次)
this.handleAgeAdd = this.handleAgeAdd.bind(this)
复制代码

补充:

1. input 中的 onchange 事件中有一个event对象

handleInputChange = (e) => {
    console.log(e)
  }
复制代码
<input
  type="text"
  onChange={this.handleInputChange}
/>
复制代码

handleInputChange = (e) => {
    console.log(e.target)
  }
复制代码

2.push的返回值

todos: this.state.todos.push(todo)
复制代码

注意:

这里的push要出错,因为push是更改了原来state里的值,但是返回的值又是一个长度,所以这样得到的todos就是一个数字,而不是一个数组

可以写成:

this.setState({
1.todos: this.state.todos.concat(todo)
2.todos: [...this.state.todos, todo]
3.todos: this.state.todos.slice().concat(todo)
})

// 深拷贝: 为了不破坏原有的值,我们需要深拷贝,JSON的方式做深拷贝,如果拷贝的内容中含有方法,则不可以拷贝
4.const todos = cloneDeep(this.state.todos)
    todos.push(todo)
    this.setState({
      todos
    })
5.const todos = JSON.parse(JSON.stringify(this.state.todos))
    todos.push(todo)
        this.setState({
          todos
        })
复制代码

3.createRef

// 要想使用ref, 需要引入createRef方法
import React, { Component, createRef } from 'react'

export default class Input extends Component {
  constructor() {
    super()
    // 初始化一个ref
    this.input = createRef();
  }
  
  handleAddClick = () => {
    this.setState({
      inputValue: ''
    }, () => {
      // 获取ref
      console.log(this.input.current)
      // 添加完成之后,自动获取焦点
      this.input.current.focus()
    })
  }
  
  render() {
    return (
      <div>
        <input
          type="text"
          // 给input的ref赋值
          ref={this.input}
          value={this.state.inputValue}
          onChange={this.handleInputChange}
        />
        <button onClick={this.handleAddClick}>添加</button>
      </div>
    )
  }
复制代码

聚焦之前

自动获取焦点

转载于:https://juejin.im/post/5c20b9756fb9a04a0c2e75da

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值