React第一个demo 时间记录器

	我们最终做到的页面效果是这样的:



1、工程的创建

首先,我们在创建工程之前,要将react-create-app ,装入我们的系统中:
npm install -g create-react-app

稍微解释一下 ,npm相当于Linux中的包管理器 apt-get,详情我会再写篇文章,专门讲解开发前期的系统配置。React 环境搭建
新工程的创建相对简单,直接在想要创建的目录下 ,命令行输入
create-react-app asia_timer
经过一系列的等待之后,我们的应用就创建好了。

2、导入项目

将创建好的项目,导入到我们的开发IDE中去。这里我用的是WebStorm,因为它跟AndroidStudio用的都是同一个核心ide.
项目在创建时,系统会自动生成一个类似Hello World 的小代码,我们可以直接在WebStorm的Terminal中,输入命令
npm start
来启动这个示例程序。效果如下:

3、进入真正的编程

我们这里将整个项目分成上中下三个部分来进行组件式开发。这样有利于后期的修改和维护。
主要的组件我们创建为 TimeDisplay类,在这个类中,我们将进行3个部分的组合,和内部逻辑的代码编写。

a.上部时间区

上部的展示最简单,只需要一个h1标签即可。
var time = formatTime(this.state.time);
<h1 className="display-time">{time}</h1>
,我们可以看到,实际上展示的就是这个time,那这个元素我们怎么去获取呢?
其实这个是我们根据状态中的一个自定义time值,通过格式转换来获取的。
我们在TimeDisplay的构造函数中,对状态进行了初始化赋值。
    //在构造函数中对状态赋初始值
    constructor(props){
        super(props);
        //不能调用state
        this.state = {
            time:0,//上部的时间值
            on:false,//按钮开始和暂停的控制状态
            log:[] //数组 用于下部的记录
        };
    }
我们的思路是,构造函数中定义了这个time,然后在用户按开始按钮事,去动态的改变这个time(做+1 和 格式化处理),这样,系统就会自动的调用render()方法,重新绘制整个页面,从而在绘制上部h1标签时,将最新的time绘制到界面上去。

b.中部按钮区域组件开发

这四个按钮,我是直接自定义了一个Button组件
import React from 'react';

class Button extends React.Component{
    //静态属性,给属性赋默认值
    static defaultProps = {
        onClick : null,
        className : '',
        text : '默认'
    };

    render(){
        return <button className={`Button ${this.props.className}`} onClick={this.props.onClick}>{this.props.text}</button>;
    }
}

export default Button;

在defayltProps中,设置了默认的几个属性值,这样在后面我们的TimeDisplay中,可以方便的赋值。

c.下部log部分的开发

代码注释都很清楚了,我就不写什么描述了
import React from 'react';
import formatTime from '../utils/formatTime';

class DisplayLog extends React.Component{
        //log数组长度等于0,返回“空空如也”
    renderEmpty = () =>{
        return <span className="empty-log">空空如也...</span>;
    }

    //否则,把元素遍历(时间),得到一系列的<li>
    renderLog = () => {
        //<li>00</li>
        //<li>11</li>
        return this.props.log.map(item => { //css3 的遍历方法
            return <li className="log-item" >{formatTime(item)}</li>;
        });
    }

    render(){
        //log数组长度等于0,返回“空空如也”
        //否则,把元素遍历(时间),得到一系列的<li>
        //<ul>
        //  <li>00</li>
        //  <li></li>
        //</ul>
        const log = this.props.log.length === 0 ? this.renderEmpty() : this.renderLog();
        return <ul className="log">
            {log}
        </ul>;
    }
}

export default DisplayLog;


4、组装类 TimeDisplay


import React from 'react';

import DisplayLog from './DisplayLog';
import Button from './Button';
import formatTime from '../utils/formatTime';

class TimeDisplay extends React.Component{
    //在构造函数中对状态赋初始值
    constructor(props){
        super(props);
        //不能调用state
        this.state = {
            time:0,
            on:false,
            log:[] //数组
        };
    }

    //开始按钮
    handleToggle = ()=>{
        //已经开始,取消正在运行的定时器
        if(this.state.on){
            clearInterval(this.timer);
        }else{
            //否则开启
            //定时器,10ms累加1
            this.timer = setInterval(()=>this.setState({time:this.state.time+1}),10);
        }
        this.setState({on:!this.state.on});
    }
    //记录时间
    handleLogTime = ()=>{
        //存储在数组中
        this.state.log.push(this.state.time);
    }
    //清空记录
    handleClearLog = ()=>{
        this.setState({log:[]});
    }
    //重置
    handleReset = () =>{
        this.setState({time:0});
    }

    render(){
        var time = formatTime(this.state.time);
        return <div>
            <h1 className="display-time">{time}</h1>
            <div className="controls">
                <Button className={this.state.on ? "danger" : "success"} text={this.state.on ? "暂停" : "开始"} onClick={this.handleToggle}/>
                <Button className="warning"  onClick={this.handleReset}/>
                <Button className="primary" text="记录" onClick={this.handleLogTime}/>
                <Button className="undefined" text="清空" onClick={this.handleClearLog}/>
            </div>
            <DisplayLog log={this.state.log}/>
        </div>;
    }

    //监听键盘事件
    componentDidMount(){
        //内置对象
        window.addEventListener('keydown', e => e.preventDefault());
        window.addEventListener('keyup', e => {
            e.preventDefault();
            switch (e.keyCode){
                case 32: //space
                    this.handleToggle();
                    break;
                case 82://r R
                    this.handleReset();
                    break;
                case 13:// Enter
                    this.handleLogTime();
                    break;
                case 67://c C
                    this.handleClearLog();
                    break;
                default:
                    break;
            }
        });
    }

    //组件被移除,事件监听取消
    componentWillUnmount(){
        window.removeEventListener('keydown');
        window.removeEventListener('keyup');
    }

}

//在外部要使用TimeDisplay
export default TimeDisplay;

在这个类中,我们将各个组件组装上,并且传入相应的属性和函数。这样就能够达到最后的效果。
当然,想要达到好看的效果,样式是非常重要的,我们将样式统一写在App.css中,便于管理,和提高代码可读性。

这是第一篇编码文章,如果有什么写的不好的地方,欢迎大家批评和指正。
我们这里将整个项目分成上中下三个部分来进行组件式开发。这样有利于后期的修改和维护。
我们这里将整个项目分成上中下三个部分来进行组件式开发。这样有利于后期的修改和维护。
展开阅读全文

没有更多推荐了,返回首页