React学习之state与生命周期

说明:本系列所有demo代码的github地址为:https://github.com/Brucewu998/react.js-learning,笔者会不断更新这些代码,本篇代码在目录下demo-05文件夹下。

React学习之组件与props这一节中,讲述了React相关的传值机制props,我们知道React对props由严格的保护机制,一旦给定值,在组件中是不允许改变的;在很多场合中,组件的内容需要根据数据的刷新而刷新,这个时候就可以用到React提供的State,在这里称之为状态机,State与props都是React的私有的,但不同的是,State是完全受控于组件的,所定义的属性值可以根据需求而改变,并在虚拟DOM上同步更新。在React中,state的创建方式为:

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = { // 状态机
            value: "Hello"
        }
     }
}

由上面代码可知,利用ES6的class继承方法super,可以将props传递到React.Component的构造函数中。

这里我们以一个更详细的例子来看React的state(状态机)和生命周期:

class Clock extends React.Component {
      constructor(props) {
          super(props);
          this.state = { // 状态机
              date: new Date()
          }
      }

      componentDidMount() {
          this.timerID = setInterval(
              () => this.tick(),
                    1000
           )
      }

      tick() {
          this.setState({ // setState用于更新组件的state
              date: new Date()
          });
      }

      componentWillUnmount() {
          clearInterval(this.timerID);
      }

      render() {
          return (
              <div>
                  <h1>现在的时间:</h1>
                  <h2 className="h2">{ this.state.date.toLocaleTimeString() }</h2>
              </div>
          )
      }
}

上面的代码,创建了一个计时器组件,在这个计时器组件中,包含了两个方法,componentDidMount和componentWillUnmount,这两个方法称之为生命周期方法,当Clock组件第一次被渲染到DOM中的时候,设置一个计时器,用于不断地更新状态机中的date值,这个阶段在React中称之为挂载(mount),同时,当组件被销毁时,应该释放占用的相应资源,这个时候,componentWillUnmount方法就可以用于清除计时器,这在React中称之为卸载(unmount),将相应占用的资源释放掉。关于组件的生命周期相关可以参考:https://zh-hans.reactjs.org/docs/react-component.html#the-component-lifecycle

上面的代码还实现了一个tick的方法,用于更新date这个值;我们可以注意到,这里用了setState这个方法,这是从React.Component中继承而来的一个用于更新状态机(state)中的值的方法,这个方法一般有两种应用的情况:

this.setState({ 
    date: new Date() //直接更新
});

另外一种是需要给setState传一个回调函数来更新值,这个回调函数将整个状态机state作为参数:

class Clock extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            date: new Date(),
            show: true,
            text: "隐藏"
        }
        this.handleClickShow = this.handleClickShow.bind(this);
    }

    handleClickShow(){
        this.setState(state => ({
            show: !state.show,
            text: !state.show ? "隐藏" : "显示"
        }))
    }
}

那么为什么要用回调函数呢?因为在鼠标或者键盘监听事件中,会存在作用域的问题,往往使得this不是指向当前的组件类,所以在构建该组件类时,如果又涉及到相应监听代码,应该进行这个操作:this.handleClickShow = this.handleClickShow.bind(this),

以保证在这个方法内可以正确的访问到this。

这个demo的完整代码如下,也可以去github中查看代码:demo-05.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="../build/react.dev.js"></script>
    <script src="../build/react-dom.dev.js"></script>
    <script src="../build/brower.min.js"></script>
    <title>Demo-07</title>
</head>
<body>
    <div id="demo-7"></div>
    <script type="text/babel">
        class Clock extends React.Component {
            constructor(props) {
                super(props);
                this.state = { // 状态机
                    date: new Date(),
                    show: true,
                    text: "隐藏"
                }
                this.handleClickShow = this.handleClickShow.bind(this);
            }

            componentDidMount() {
                this.timerID = setInterval(
                    () => this.tick(),
                    1000
                )
            }

            tick() {
                this.setState({ // setState用于更新组件的state
                    date: new Date()
                });
            }

            handleClickShow() {
                this.setState(state => ({
                    show: !state.show,
                    text: !state.show ? "隐藏" : "显示"
                }))
                
            }

            componentWillUnmount() {
                clearInterval(this.timerID);
            }

            render() {
                let isShow = this.state.show;
                let element;
                if (isShow) {
                    element = <h2 className="h2">{ this.state.date.toLocaleTimeString() }</h2>
                } else {
                    element = null;
                }
                return (
                    <div>
                        <button onClick={this.handleClickShow}>{this.state.text}计时器</button>
                        {element}
                    </div>
                )
            }
        }
        ReactDOM.render(
            <Clock />,
            document.getElementById("demo-7")
        )
    </script>
</body>
</html>
<style>
    .h2 {
        color: blue;
    }
</style>

上面的demo中,涉及到了条件渲染的知识,这个后边会做详细的讲解。 

效果:

 

上一篇: React学习之获取真实DOM节点

下一篇:React学习之事件处理​​​​​​​

技术选型 【后端】:Java 【框架】:springboot 【前端】:vue 【JDK版本】:JDK1.8 【服务器】:tomcat7+ 【数据库】:mysql 5.7+ 项目包含前后台完整源码。 项目都经过严格调试,确保可以运行! 具体项目介绍可查看博主文章或私聊获取 助力学习实践,提升编程技能,快来获取这份宝贵的资源吧! 在当今快速发展的信息技术领域,技术选型是决定一个项目成功与否的重要因素之一。基于以下的技术栈,我们为您带来了一份完善且经过实践验证的项目资源,让您在学习和提升编程技能的道路上事半功倍。以下是该项目的技术选型和其组件的详细介绍。 在后端技术方面,我们选择了Java作为编程语言。Java以其稳健性、跨平台性和丰富的库支持,在企业级应用中处于领导地位。项目采用了流行的Spring Boot框架,这个框架以简化Java企业级开发而闻名。Spring Boot提供了简洁的配置方式、内置的嵌入式服务器支持以及强大的生态系统,使开发者能够更高效地构建和部署应用。 前端技术方面,我们使用了Vue.js,这是一个用于构建用户界面的渐进式JavaScript框架。Vue以其易上手、灵活和性能出色而受到开发者的青睐,它的组件化开发思想也有助于提高代码的复用性和可维护性。 项目的编译和运行环境选择了JDK 1.8。尽管Java已经推出了更新的版本,但JDK 1.8依旧是一种成熟且稳定的选择,广泛应用于各类项目中,确保了兼容性和稳定性。 在服务器方面,本项目部署在Tomcat 7+之上。Tomcat是Apache软件基金会下的一个开源Servlet容器,也是应用最为广泛的Java Web服务器之一。其稳定性和可靠的性能表现为Java Web应用提供了坚实的支持。 数据库方面,我们采用了MySQL 5.7+。MySQL是一种高效、可靠且使用广泛的关系型数据库管理系统,5.7版本在性能和功能上都有显著的提升。 得一提的是,该项目包含了前后台的完整源码,并经过严格调试,确保可以顺利运行。通过项目的学习和实践,您将能更好地掌握从后端到前端的完整开发流程,提升自己的编程技能。欢迎参考博主的详细文章或私信获取更多信息,利用这一宝贵资源来推进您的技术成长之路!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值