react 創(chuàng)造組件
// 創(chuàng)造組件的方式
// 方式一:使用class
// class Welcome extends React.Component {
// render() {
// return <h1>Hello, {this.props.name}</h1>;
// }
// }
// 方式二:使用函數(shù)
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
export default Welcome
引用:
ReactDOM.render(
<Welcome name="hexon"/>,
document.getElementById('root')
)
記?。?strong>組件不能修改它得到的props
state
組件不能改變它得到的props,那么組件中可以變的東西放在state中
注意:函數(shù)形式的組件不支持state
如何改變state
如果是直接通過給this.state賦值,是無法改變state的,必須通過this.setState來改變。
關(guān)于setState,一定要看這篇文章:setState:這個(gè)API設(shè)計(jì)到底怎么樣
關(guān)于setState需要理解以下幾點(diǎn):
- setState不會(huì)立刻改變React中state的值
- 多次setState函數(shù)調(diào)用產(chǎn)生的效果會(huì)合并,可以理解為多次調(diào)用,只有一次生效
- 了解函數(shù)式的setState用法
React中組件的生命周期
主要有三個(gè)階段:mount(掛載)、update(更新)、unmount(移除)
mount(掛載階段)
mount就是第一次讓組件出現(xiàn)在頁面中的過程。關(guān)鍵就是render()方法,React會(huì)將render()的返回值(一般是虛擬DOM、也可以是DOM或null)插入到頁面中。
這個(gè)時(shí)候會(huì)暴露幾個(gè)鉤子函數(shù)供我們往其中添加代碼,如下:
- constructor()
- componentWillMount()
- render()
- componentDidMount() :
一般在該階段進(jìn)行ajax操作
圖片展示過程如下:

image.png
update(更新階段)
mount之后,如果數(shù)據(jù)有任何變動(dòng),就會(huì)來到update過程,這個(gè)過程有5個(gè)鉤子:
- componentWillReceiveProps(nextProps) —— 已掛載的組件,在接收到新的props之前調(diào)用該函數(shù)
- shouldComponentUpdate(nextProps, nextState) —— 詢問是否要更新組件?如果返回false,則不會(huì)往下執(zhí)行,終止組件更新;如果返回true,則繼續(xù)往下執(zhí)行,
可以在該函數(shù)內(nèi)添加一些判斷,跳過不需要被更新的組件,提升性能 - componentWillUpdate() —— 我要更新組件了
- render() —— 更新
- componentDidUpdate() —— 更新完畢了:
比較適合發(fā)送ajax到服務(wù)器端的函數(shù),可以在該生命周期函數(shù)中對(duì)輸入的新props與舊props進(jìn)行比較,來決定是否發(fā)送請(qǐng)求到服務(wù)器端
unmount(移除階段)
當(dāng)一個(gè)組件要從頁面中移除時(shí),會(huì)進(jìn)入到unmount階段,該階段有一個(gè)鉤子函數(shù):
- componentWillUnmount() —— 我要被移除了
我們可以在移除之前做一些清理工作
既然React中一個(gè)組件的生命周期包含有這么三個(gè)階段,同時(shí),我們說要改變state只能通過setState進(jìn)行修改,那么可以在哪些階段使用setState對(duì)state進(jìn)行更新呢?
一般而言,只在以下幾個(gè)鉤子函數(shù)中調(diào)用setState:
- componentWillMount()
- componentDidMount()
- componentWillReceiveProps()
- componentDidUpdate()
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Number extends Component {
constructor(props) {
super(props);
console.log('%c constructor 子組件已構(gòu)造', 'font-weight: bolder', 'color: blue');
}
componentWillMount() {
console.group('%c React掛載', 'color: #00d8ff');
console.log('%c componentWillMount 組件即將掛載', 'font-weight:bold')
}
componentDidMount() {
console.log('%c componentDidMount 組件已掛載', 'font-weight:bold')
console.groupEnd();
}
componentWillReceiveProps(newProps) {
console.group("%c React Updating", 'color: green')
console.log('%c componentWillReceiveProps 組件即將接收props', 'font-weight:bold', '')
console.log('newProps', newProps.counter)
console.log('this.props', this.props.counter)
}
shouldComponentUpdate(newProps, newState) {
const result = true
console.info(`%c shouldComponentUpdate 返回判斷是否要更新組件 ${result}` , 'font-weight:bold;color: #236fd4')
if (!result) console.groupEnd()
return result;
}
componentWillUpdate(nextProps, nextState) {
console.log('%c componentWillUpdate 組件即將更新', 'font-weight:bold', '')
console.log('nextProps', nextProps.counter)
console.log('this.props', this.props.counter)
}
componentDidUpdate(prevProps, prevState) {
console.log('%c componentDidUpdate 組件已更新', 'font-weight:bold', '')
console.log('prevProps', prevProps.counter)
console.log('this.props', this.props.counter)
console.groupEnd();
}
componentWillUnmount() {
console.group("%c React Unmounting", 'color: brown')
console.log('%c componentWillUnmount 組件即將卸載','font-weight:bold' , 'color: gray')
console.groupEnd();
}
render() {
console.log('%c render 組件渲染中...', 'font-weight:bold', '')
console.log('this.props.counter', this.props.counter)
return <p>{ this.props.counter }</p>
}
}
class LifecycleCounter extends Component {
constructor(props) {
super(props);
this.state = {
counter: 0
}
}
addOne() {
this.setState((prevState) => ({
counter: prevState.counter + 1
}))
}
unMount() {
console.info(ReactDOM.unmountComponentAtNode(document.getElementById('root')));
}
update() {
this.forceUpdate();
}
render() {
return (
<div className="LifecycleCounter">
<Number counter={this.state.counter}></Number>
<button onClick={() => this.addOne()}>增加一</button>
<button onClick={() => this.update()}>強(qiáng)制更新</button>
<button onClick={() => this.unMount()}>卸載</button>
</div>
)
}
}
export {
LifecycleCounter
}