react-demo

1.创建react项目

create-react-app -v 查看是否安装react脚手架, 没有的话全局安装;

create-react-app demo 创建react项目;

npm run start启动项目;

2.根据日历上的日期计算年龄

npm install antd --save 安装antd ,注意代码中引入antd的方式;

关键点:antd的使用 、日期获得getFullYear(是num类型)、取子字符串subString

import React ,{Component} from 'react'
import {DatePicker} from "antd"
import 'antd/dist/antd.css'

class AgeComputer extends Component{
    constructor(props){
        super(props);
        this.state={
            age:''
        };
        this.handleChange=this.handleChange.bind(this);
        this.handleChange2=this.handleChange2.bind(this);
    }


    //date是一个moment对象,dateString是yyyy-mm-dd格式的日期 
    //空的话date和dateString都是null
        handleChange(date,dateString){
        console.log(date);
        console.log(dateString);
        let newAge='';
        if(dateString){
            let temp=((new Date()).getFullYear()-parseInt(dateString.substring(0,4))).toString();
            if(temp==='0'){newAge='不到一岁'}else{newAge=temp}
        }else{
            newAge='';
        }
        this.setState({
            age:newAge
        })
    }

    // 传入事件对象,可以通过e.tartget获得输入的值
    // 此处注意,setstate后不能立即使用新的值,等这个块完了之后,state才会被重置
    handleChange2(e){
        console.log("e.target.value:"+e.target.value)
        let newAge=e.target.value.toString();
        this.setState({
            age:newAge
        })
        console.log("this.state.age"+this.state.age)
    }
    render(){
        return(
            <div>
                <span>出生日期</span>
                <DatePicker onChange={this.handleChange}></DatePicker>
                <span style={{marginLeft:"50px"}}>年龄</span>
                <input type="text" value={this.state.age} onChange={this.handleChange2} ></input>
                <span>{this.state.age}</span>
            </div>
        )
    }
}
export default AgeComputer

说明:这段代码有一个问题,就是在handleChange2()中,把e.target.value传入并设置给state后,在控制台输出e.target.value和this.state.age结果并不一样,this.state.age输出的是上一次change的结果。 是因为handleChange2还没有执行完,state还没有设置,没有生效。

3.两种温度转换

两个输入框,一个输入摄氏温度,一个输入华氏温度,并且在其中一个输入框输入相应温度时,另一个也会变化。并且输出水在此温度下是否会沸腾。

思路:一个父组件,包含两个输入框组件,输入框一个是摄氏温度,一个是华氏温度。还有一个组件用于输出水会不会沸腾,只需要通过props传递进去,判断是否大于100即可。父组件管理数据状态,state里面只需要存储温度类型和数值,就可以计算出另一种类型的温度。父组件把温度值和温度类型传递给输入框子组件进行渲染。当输入框中的内容变化,会触发input的onchange事件,通过e.target.value可以设置新的值。子组件设置父组件中的值,也是父组件通过props传递的,把事件处理当作一个属性即可。

1.子组件和父组件的通信问题

   父组件传递给子组件数据用props,子组件修改父组件的数据,可以通过父组件中的this.setState(组件中的state只能在本组件中修改),只需要父组件把修改数据的事件当作属性传递给子组件即可;

2.组件中的方法,一定要绑定到this,可以写一个工具函数;

3.保留三位小数的方法

Math.round(floatNumber*1000)/1000;

4.只通过props获取数据,没有state的组件,可以使用无状态组件,只进行页面渲染。

父组件的代码:Calculator

import React ,{Component} from 'react';
import TemperatureInput from './TemperatureInput';
import BoilingVerdict from './BoilingVerdict';

function toCelsius(fahrenheit){
    return (fahrenheit-32)*5/9;
}

function toFahrenheit(celsius){
    return (celsius*9/5)+32;
}

function tryConvert(temperature,convert){
    const input = parseFloat(temperature);
    if(Number.isNaN(input)){
        return '';
    }
    const output = convert(input);
    // 目的是为了保留三位小数
    const rounded = Math.round(output*1000)/1000;
    return rounded.toString();
}

class Calculator extends React.Component{
    constructor(props){
        super(props);
        this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
        this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
        this.state = {
            temperature:'',
            scale:'c'
        };
    }

    handleCelsiusChange(temperature){
        this.setState({scale:'c',temperature});
    }
    handleFahrenheitChange(temperature){
        this.setState({scale:'f',temperature});
    }
    render(){
        const scale = this.state.scale;
        const temperature = this.state.temperature;
        const celsius = scale === 'f' ? tryConvert(temperature,toCelsius) : temperature;
        const fahrenheit = scale === 'c' ? tryConvert(temperature,toFahrenheit) : temperature;
        return (
            <div>
                <TemperatureInput scale="c" temperature={celsius} onTemperatureChange={this.handleCelsiusChange}/>
                <TemperatureInput scale="f" temperature={fahrenheit} onTemperatureChange={this.handleFahrenheitChange}/>
                {/* {celsius>=100 ? <p>the water would boil</p> :<p>the water would not boil.</p>} */}
                <BoilingVerdict celsius={parseFloat(celsius)} />
            </div>
        );
    }
    
}

export default Calculator;

子组件代码:TemperatureInput

import React ,{Component} from 'react';


const scaleNames = {
    c:'Celsius',
    f:'Fahrenheit'
}

class TemperatureInput extends React.Component{
    constructor(props){
        super(props);
        this.handeleChange = this.handeleChange.bind(this);
    }

    handeleChange(e){
        
        this.props.onTemperatureChange(e.target.value);
    }

    render(){
        const temperature = this.props.temperature;
        const scale = this.props.scale;
        return (
            <fieldset>
                <legend>Enter temperature in {scaleNames[scale]}</legend>
                <input value={temperature} onChange={this.handeleChange}/>
            </fieldset>
        );
    }
}

export default TemperatureInput

    判断水是否沸腾组件:

import React from 'react';

function BoilingVerdict(props){
    if(props.celsius >=100){
        return <p>the water would boil.</p>;
    }
    return  <p>the water would not boil.</p>
}

export default BoilingVerdict;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章