React的属性/状态/表单和生命周期
一、Props(属性)
- 组件像一个函数一样,接受特定的输入(props),产出特定的输出(React elements)
- V=f(props)
eg:属性Props实例-一张名片
- 安装bootstrap样式
npm install bootstrap --save
- 在index.js中引入bootstrap
import 'bootstrap/dist/css/bootstrap.min.css';
- 新建components文件夹存放组件,NameCard.js引入依赖
import React from 'react'
class NameCard extends React.Component{
render(){
const { name, number,isHuman,tags} = this.props
return(
<div className="alert alert-success">
<h4 className="alert-heading">{name}</h4>
<ul>
<li>电话:{number}</li>
<li>{isHuman ? '人类' : '外星生物'}</li>
<p>
{ tags.map((tag,index) => (
<span className="badge badge-pill badge-primary " key={index}>{tag}</span>
))}
</p>
</ul>
</div>
)
}
}
export default NameCard
- App.js中引入components
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import NameCard from './components/NameCard';
const tags=['好','很好']
class App extends Component{
render(){
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcom to React</h1>
</header>
<NameCard name="lili" number={12334} isHuman tags={tags}/>
</div>
);
}
}
export default App;
- 函数式写法
import React from 'react'
const NameCard = (props) =>{
const { name, number, isHuman, tags} = props
return(
<div className="alert alert-success">
<h4 className="alert-heading">{name}</h4>
<ul>
<li>电话:{number}</li>
<li>{isHuman ? '人类' : '外星生物'}</li>
<p>
{ tags.map((tag,index) => (
<span className="badge badge-pill badge-primary " key={index}>{tag}</span>
))}
</p>
</ul>
</div>
)
}
export default NameCard
- 效果展示
二、State(状态)
- 组件内部的数据可以动态改变
- this.setState()是更新state的唯一途径
eg:State实例-点赞按钮
- components下新建LikesButton.js
import React from 'react';
class LikesButton extends React.Component{
constructor(props){
super(props)
this.state = {
likes : 0
}
}
render(){
return (
<div className="Likes-button-component">
<button
type="button"
className="btn btn-outline-prmary btn-lg">
<span className="glyphicon glyphicon-thumbs-up" aria-hidden="true"/>
{this.state.likes}
</button>
</div>
)
}
}
export default LikesButton
- App.js文件引入
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import NameCard from './components/NameCard';
import LikesButton from './components/LikesButton';
const tags=['好','很好']
class App extends Component{
render(){
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcom to React</h1>
</header>
{}
{}
<LikesButton />
</div>
);
}
}
export default App;
- 效果图
- 点击点赞按钮增加次数
- 采用驼峰式命名onClick传入函数处理
- 创建传入的函数
- this没有进行绑定回调函数,需要手动绑定
方法一:this.increaselikes = this.increaselikes.bind(this)
方法二:使用箭头函数 onClick={()=>{this.increaselikes()}} - 调用this.state方法,实现likes值加一
import React from 'react';
class LikesButton extends React.Component{
constructor(props){
super(props)
this.state = {
likes : 0
}
this.increaselikes = this.increaselikes.bind(this)
}
increaselikes(){
this.setState({
likes:++this.state.likes
})
}
render(){
return (
<div className="Likes-button-component">
<button
type="button"
className="btn btn-outline-prmary btn-lg"
onClick={()=>{this.increaselikes()}}
>
<span className="glyphicon glyphicon-thumbs-up" aria-hidden="true"/>
{this.state.likes}
</button>
</div>
)
}
}
export default LikesButton
三、生命周期
- 组件初始化:一个组件从开始到DidMount dom节点的过程
- 组件更新:调用State之后从开始到组件更新完毕之后的过程
- 组件卸载:一个组件从dom节点上卸载的过程
- React生命周期图解
eg:生命周期实例-电子钟表
- 需求分析:初始化显示当前时间,组件添加定时器,每一秒更新到当前时间,组件销毁时要销毁定时器
- 在components文件里新建DigitalClock.js文件
import React from 'react';
class DigitalClock extends React.Component{
constructor(props) {
super(props)
this.state = {
date : new Date()
}
}
render() {
return(
<div className="digital-clock-component jumbotron">
<h1>{this.state.date.toLocaleTimeString()}</h1>
</div>
)
}
}
export default DigitalClock
- 在App.js中引入
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import DigitalClock from './components/DigitalClock';
class App extends Component{
render(){
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcom to React</h1>
</header>
<DigitalClock/>
</div>
);
}
}
export default App;
- 在组件Mount之后添加定时器
– componentDidMount() - 加载之后卸载定时器
– componentWillUnmount()
import React from 'react';
class DigitalClock extends React.Component{
constructor(props) {
super(props)
this.state = {
date : new Date()
}
}
componentDidMount() {
this.timer = setInterval(()=>{
this.setState({
date : new Date()
})
},1000)
}
componentWillUnmount() {
clearInterval(this.timer)
}
render() {
return(
<div className="digital-clock-component jumbotron">
<h1>{this.state.date.toLocaleTimeString()}</h1>
</div>
)
}
}
export default DigitalClock
- 扩展
– componentDidUpdate(props,state)使用讲解
传入两个参数,实时更新的props和实时更新的state
componentDidUpdate(currentProps, currentState){
console.log(currentState)
}
- 效果图
四、Forms(表单)
- 表单元素和其他DOM元素存在区别
- Controlled Components -受控组件
eg:表单实例-留言板
- 需求分析
输入留言内容后点击回车或者提交按钮弹出留言框里内容 - 在components文件里新建ComponentBox.js文件
import React from "react";
class ComponentBox extends React.Component{
constructor(props) {
super(props)
this.state = {
value : ''
}
}
render(){
return(
<form className="p-5">
<div className="form-group">
<label>留言内容</label>
<input
type="text"
className="form-control"
placeholder="请输入内容"
value={this.state.value}
/>
</div>
<button type="submit" className="btn btn-primary">留言</button>
</form>
)
}
}
export default ComponentBox
- 在App.js中引入ComponentBox
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import ComponentBox from './components/ComponentBox';
class App extends Component{
render(){
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcom to React</h1>
</header>
<ComponentBox/>
</div>
);
}
}
export default App;
- 将静态页面改为交互页面
– 受控组件onChange
弊端:使用繁琐,为数据变化的美一种方式编写一个事件
import React from "react";
class ComponentBox extends React.Component{
constructor(props) {
super(props)
this.state = {
value : ''
}
this.handChange = this.handChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleSubmit(event){
alert(this.state.value)
event.preventDefault()
}
handChange(event){
this.setState({
value: event.target.value
})
}
render(){
return(
<form className="p-5" onSubmit={this.handleSubmit}>
<div className="form-group">
<label>留言内容</label>
<input
type="text"
className="form-control"
placeholder="请输入内容"
onChange={this.handChange}
value={this.state.value}
/>
</div>
<button type="submit" className="btn btn-primary">留言</button>
</form>
)
}
}
export default ComponentBox
- 使用受控组件
– ref
import React from "react";
class ComponentBox extends React.Component{
constructor(props) {
super(props)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleSubmit(event){
alert(this.textInput.value)
event.preventDefault()
}
render(){
return(
<form className="p-5" onSubmit={this.handleSubmit}>
<div className="form-group">
<label>留言内容</label>
<input
type="text"
className="form-control"
placeholder="请输入内容"
ref={(textInput) => {this.textInput = textInput}}
/>
</div>
<button type="submit" className="btn btn-primary">留言</button>
</form>
)
}
}
export default ComponentBox