• React笔记 #04# 对state的理解


    饮水思源:https://www.bilibili.com/video/BV1wy4y1D7JT?p=12

    一句话:状态驱动页面,状态改变,页面改变。

    简单组件

    被传入的数据可在组件中通过 this.props 在 render() 访问。

      <script type="text/babel">
        let 容器 = document.querySelector("#test");
        class 这是一个简单组件 extends React.Component {
          render() {
            console.log(this) 
            return <h2>我是{this.props.name}</h2>
          }
        }
        ReactDOM.render(<这是一个简单组件 name={"火车王"} />, 容器);
      </script>

    有状态组件

    直接抄官网:除了使用外部数据(通过 this.props 访问)以外,组件还可以维护其内部的状态数据(通过 this.state 访问)。当组件的状态数据改变时,组件会再次调用 render() 方法重新渲染对应的标记。

    解决类中this指向问题:https://www.bilibili.com/video/BV1wy4y1D7JT?p=16

    效果演示(点击文字改变):

    状态不能直接更改,要借助内部API更改(严重注意!),且setState是合并不是替换。错误示例:

      <script type="text/babel">
        let 容器 = document.querySelector("#test");
    
        let that;
        class 这是一个有状态的组件 extends React.Component {
          constructor(props) {
            super(props) // 为了接属性
            this.state = {
              name: "火车王",
            }
    
            that = this;
          }
    
          render() {
            console.log(this) 
            return <h2 onClick={changeName}>我是{this.state.name}</h2>
          }
        }
    
        ReactDOM.render(<这是一个有状态的组件 />, 容器);
    
        function changeName() {
          console.log(that)
          console.log("函数被" + that.state.name + "触发");
          if (that.state.name == "火车王") {
            that.state.name = "火车王的儿子"
          } else {
            that.state.name = "火车王"
          }
        }
      </script>
    无效代码

    采用setState。写法一:

        let 容器 = document.querySelector("#test");
    
        let that;
        class 这是一个有状态的组件 extends React.Component {
          constructor(props) {
            super(props) // 为了接属性
            this.state = {
              name: "火车王",
            }
    
            that = this;
          }
    
          render() {
            return <h2 onClick={changeName}>我是{this.state.name}</h2>
          }
        }
    
        ReactDOM.render(<这是一个有状态的组件 />, 容器);
    
        function changeName() {
          let str;
          if (that.state.name == "火车王") {
            str = "火车王的儿子"
          } else {
            str = "火车王"
          }
          that.setState({name: str});
        }

    写法二:

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8" />
      <title>Add React in One Minute</title>
    </head>
    
    <body>
      <div id="test"></div>
      <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
      <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
      <!-- Load Babel -->
      <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    
      <script type="text/babel">
        let 容器 = document.querySelector("#test");
    
        class 这是一个有状态的组件 extends React.Component {
          constructor(props) {
            super(props) // 为了接属性
            this.state = {
              name: "火车王",
            }
            this.changeName = changeName.bind(this);
          }
    
          render() {
            return <h2 onClick={this.changeName}>我是{this.state.name}</h2>
          }
        }
    
        ReactDOM.render(<这是一个有状态的组件 />, 容器);
    
        function changeName() {
          let str;
          if (this.state.name == "火车王") {
            str = "火车王的儿子"
          } else {
            str = "火车王"
          }
          this.setState({name: str});
        }
      </script>
    </body>
    </html>

    把changeName挂在原型上也行:

        let 容器 = document.querySelector("#test");
    
        class 这是一个有状态的组件 extends React.Component {
          constructor(props) {
            super(props) // 为了接属性
            this.state = {
              name: "火车王",
            }
            this.changeName = this.changeName.bind(this);
          }
    
          render() {
            console.log(this);
            return <h2 onClick={this.changeName}>我是{this.state.name}</h2>
          }
          
          changeName() {
            let str;
            if (this.state.name == "火车王") {
              str = "火车王的儿子"
            } else {
              str = "火车王"
            }
            this.setState({name: str});
          }
        }
    
        ReactDOM.render(<这是一个有状态的组件 />, 容器);

    必须注意,this.changeName = this.changeName.bind(this);是必要的,因为onClick时,changeName是作为回调函数调用的,而不是通过对象实例调用,也就是说,他的this的指向是有问题的。

    简写形式。在class中直接写赋值语句是直接挂在对象上而不是原型上的,必须用箭头函数而不可以用function,箭头函数没有自己的this:

      <script type="text/babel">
        let 容器 = document.querySelector("#test");
    
        class 这是一个有状态的组件 extends React.Component {
    
          state = { // 在对象上
            name: "火车王",
          }
    
          changeName = () => { // 自定义方法,在对象上,不在对象原型上
    
            console.log(this);
    
            let str;
            if (this.state.name == "火车王") {
              str = "火车王的儿子"
            } else {
              str = "火车王"
            }
            this.setState({name: str});
          }
    
          render() {
            return <h2 onClick={this.changeName}>我是{this.state.name}</h2>
          }
        }
    
        ReactDOM.render(<这是一个有状态的组件 />, 容器);
      </script>

    小结

    强烈注意,render方法中的this为组件实例对象

    组件自定义方法中的this在作为回调函数调用时,为undefined,解决办法是:

    通过bind()强制绑定this;或者,在class中写箭头函数,因为箭头函数本身不带this

  • 相关阅读:
    一个2013届毕业生(踏上IT行业)的迷茫(2)
    一个2013届毕业生(踏上IT行业)的迷茫(1)
    Java 开源博客——B3log Solo 0.6.5 正式版发布了!
    Java 开源博客——B3log Solo 0.6.5 正式版发布了!
    在CSDN博客中添加量子恒道统计功能的做法
    Struts2——(8)struts2中文件的上传
    Struts2——(7)拦截器组件
    让富文本编辑器支持复制doc中多张图片直接粘贴上传
    ASP net 上传整个文件夹
    js文件夹上传
  • 原文地址:https://www.cnblogs.com/xkxf/p/15708267.html
Copyright © 2020-2023  润新知