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;