React基础—state组件使用及分类

1. setState的简单实践和理解

比如说,我们需要定义一个列表组件。当点击奇数列表的时候随机调换一下顺序;当点击偶数列表的时候在其后加=和不加=号之间切换。

1.1 代码实现

<body>
<div id="test"></div>

<script crossorigin src="./js/react.development.js"></script>
<script crossorigin src="./js/react-dom.development.js"></script>
<script src="./js/babel.min.js"></script>

<script type="text/babel">
  var root = document.getElementById("test")


  class MyElement extends React.Component {
      
      

    constructor() {
      
      
      super();
      this.state = {
      
      datas: ["张三", "李四", "王五"]}
    }

    userClick(index) {
      
      
      let flag = index % 2 === 0
      if (flag) {
      
       // 奇数列表项乱序切换
        let temp_list = []
        for (let i = 0; i < this.state.datas.length; i++) {
      
      
          if (i % 2 === 0) {
      
      
            temp_list.push(this.state.datas[i])
          }
        }
        temp_list.sort(() => Math.random() - 0.5)
        let temp_data = []
        let j = 0
        for (let i = 0; i < this.state.datas.length; i++) {
      
      
          if (i % 2 === 0) {
      
      
            temp_data.push(temp_list[j])
            j++
          } else {
      
      
            temp_data.push(this.state.datas[i])
          }
        }
        this.setState({
      
      datas: temp_data})
      } else {
      
       // 等号和没等号之间切换
        let temp_list = []
        let switchFlag = false
        if(this.state.datas[1] != null && this.state.datas[1].endsWith("=")) {
      
      
          switchFlag = true
        }
        for (let i = 0; i < this.state.datas.length; i++) {
      
      
          if (i % 2 !== 0) {
      
      
            if (!switchFlag) {
      
      
              temp_list.push(this.state.datas[i] + "=")
            } else {
      
      
              temp_list.push(this.state.datas[i].substring(0, this.state.datas[i].length - 1))
            }
          } else {
      
      
            temp_list.push(this.state.datas[i])
          }
        }
        this.setState({
      
      datas: temp_list})
      }
    }

    render() {
      
      
      return (
        <ul>
          {
      
      
            this.state.datas.map((item, index) => {
      
      
              return <li key={
      
      index} onClick={
      
      () => {
      
      
                this.userClick(index)
              }}>{
      
      item}</li>
            })
          }
        </ul>
      )
    }
  }

  ReactDOM.render(<MyElement/>, root)
</script>
</body>

注意到这里更新数据的时候使用了:

this.setState({
    
    datas: temp_list})

且数据声明也放置在了构造器中:

constructor() {
    
    
      super();
      this.state = {
    
    datas: ["张三", "李四", "王五"]}
    }

那么,为什么需要这么写?

1.2 分析

对于下面极简的类组件:

class MyElement extends React.Component {
    
    
  constructor() {
    
    
    super();
    console.log(this)
  }
  render() {
    
    
    return (
     <div>Hello!</div>
    )
  }
}

运行后可以在控制台看见打印的实例:
在这里插入图片描述

也就是在自定义组件,继承自React.Component的时候,默认就带有一个为null的属性state。如果我们需要做到数据的动态更新,就需要使用state这个属性,并且在使用的时候,需要使用setState来进行更新。

2. 函数组件state、类组件state

2.1 函数组件state

比如下面定义一个简单的函数组件:

function Demo() {
    
    
  return (
    <div>Hello!</div>
  )
}

经过babel翻译后为:

"use strict";

function Demo() {
    
    
  return /*#__PURE__*/React.createElement("div", null, "Hello!");
}

我们知道在Rect函数组件中只有props,没有refs以及state。如果需要使用state需要引入外部的钩子。比如:

function Demo(props) {
    
    
    console.log(props)
    const [flag, setFlag] = useState(false)
    const handleClick = () => {
    
    
        setFlag(!flag)
    }

    return (
        <div onClick={
    
    handleClick}>Hello! flag is {
    
    flag ? 'true': 'false'}</div>
    )
}

root.render(
    <Demo name={
    
    "张三"} />
);

在申明state变量的时候,就指定了变量名和更新这个值状态的方法,即:

const [flag, setFlag] = useState(false)

2.2 类组件state

import React from "react";

class ClassState extends React.Component{
    
    

    constructor() {
    
    
        super();
        this.state = {
    
    name: '李四', age: 12}
    }

    handleClick = () => {
    
    
        const pre_age = this.state.age
        this.setState({
    
    age: pre_age + 1})
    }

    render(){
    
    
        const {
    
    name, age} = this.state
        return (
            <div>Hello! class state. Info: <br/>
                <p>姓名:{
    
    name}</p>
                <p>年龄:{
    
    age}</p>
                <button onClick={
    
    this.handleClick}>点击修改</button>
            </div>
        )
    }
}

export default ClassState

在这里插入图片描述

点击按钮可以将用户年龄增加。值得注意的是,这里使用this.setState来更新的时候,并不需要将没有发生改变的用户name字段重新赋值。这里也可以发现,setState不是覆盖,而是对比差异,然后更新。

猜你喜欢

转载自blog.csdn.net/qq_26460841/article/details/124992026