您好,登錄后才能下訂單哦!
?
?
目錄
React:... 1
props:... 1
constructor,構造器:... 3
組件的生命周期:... 4
?
?
?
?
?
props(properties)是公有public屬性,組件外可以訪問,但只讀,修改會報錯Uncaught TypeError: Cannot assign to read only property 'schoolName' of #<Object>;
state是private私有屬性,組件外無法直接訪問,可修改state,但建議使用setState方法;
import React from "react";
import ReactDom from 'react-dom';
?
class Toggle extends React.Component {
? state = {
??? flag: true
? };
?
? handleClick(event) {
??? // console.log(event);
??? // console.log(event.target);
??? // console.log(event.target.id);
??? // console.log(event.target === this);
??? // console.log(this);
??? // console.log(this.state);
??? let x = event.target;
??? alert("觸發的元素的id是:" + x.id);
??? this.setState({flag:!this.state.flag});
??? // this.props.schoolName='www.magedu';?? //不允許修改,Uncaught TypeError: Cannot assign to read only property 'schoolName' of #<Object>
? }
?
? render() {
??? let text = this.state.flag?'true':'flase';
??? return (<div id='t1' onClick={this.handleClick.bind(this)}>
????? {this.props.schoolName} 點擊這句話,會觸發一個事件,并彈出一個警示框<br />
????? flag = {text}
????? {console.log(this.props.parent)}?? //可操作parent里的所有屬性和方法,即在Toggle內部可操作所有對象
????? {/* {this.props.parent={}} */}?? //不可修改,若為{this.props.setState(...)}這是可以的,schoolName、this不能改,類似const a=100;,類似py中元組中的引用類型,如const a=Obj;,Obj這個對象不能動,但對象內部的屬性可隨時改
????? {this.props.children}
??? </div>);
? }
}
?
class Root extends React.Component {
? render() {
??? return (<div>
????? my first test<hr />
????? {/* <Toggle schoolName='magedu' parent={this}/> */}?? //通過屬性傳入數據到props,由外向內傳遞,常用此種,parent={this},this即為Root
????? <Toggle schoolName='magedu' parent={this}>?? //用<Toggle></Toggle>這樣定義,可定義子元素,很少用,使用時在Toggle類的render里this.pros.children
??????? <hr />?? {/*//通過子元素傳遞數據 */}?? //注釋表達式,表達式只能一行
??????? <div>我是Toggle的子元素</div>?? //通過子元素傳入數據到props的children
????? </Toggle>
??? </div>);
? }
}
?
ReactDom.render(<Root />, document.getElementById('root'));
?
?
使用ES6的構造器,要提供一個參數props,并把這個參數使用super傳遞給父類;
class Toggle extends React.Component {
? constructor(props) {
??? console.log(props);
??? super(props);
??? this.state = {
????? flag:true
??? }
? }
? // constructor(...props) {
? //?? console.log(props);
? //?? super(...props);
? //?? this.state = {
? //???? flag:true
? //?? };
? // }
?
?
?
分為三個狀態:
mounting,已插入真實的dom;
updating,正在被重新渲染;
unmounting,已移出真實dom;
?
組件的生命周期狀態,在不同時機訪問組件,組件正處在生命周期的不同狀態上,在不同的生命周期狀態訪問,就產生不同的方法;
?
注:
constructor是最早執行的函數;
?
?
生命周期的方法:
大多數時候,用不到這些函數,這些鉤子函數是為了精確地控制;
裝載組件觸發:
componentWillMount,在渲染前調用,在客戶端也在服務端,只會在裝載之前調用一次;第1次裝載,在首次render之前,如控制state、props;
componentDidMount,在第一次渲染后調用,只在客戶端,之后組件已生成了對應的dom結構,可通過this.getDomNode()來進行訪問,如果想和其它js框架一起使用,可在這個方法中調用setTimeout、setInterval或發送ajax請求等操作(防止異步操作阻塞ui),只在裝載完成后調用一次,在render之后;第1次裝載結束,在首次render之后,如控制state、props;
?
更新組件觸發:
這些方法不會在首次render組件的周期調用;
componentWillReceiveProps(nextProps),在組件接收到一個新的props時被調用,此方法在初始化render時不會被調用;在組件內部,props是只讀不變的,但是這個函數可接收到新的props,可對props作一些處理,this.props={name:'rooooot'},這就是偷梁換柱,componentWillReceiveProps觸發,也會走shouldComponentUpdate;
shouldComponentUpdate(nextProps,nextState),返回一個布爾值,在組件接收到新的props或state時被調用,在初始化時或使用forceUpdate時不被調用;可在確認不需要更新組件時使用;若設置為false,就是不允許更新組件,那componentWillUpdate、componentDidUpdate不會執行;判斷是否需要組件更新,就是是否render,精確地控制渲染,提高性能;
componentWillUpdate(nextPropx,nextState),在組件接收到新的props或state,但還沒有render時被調用,在初始化時不會被調用;在除了首次render外,每次render前執行,componentDidUpdate在render之后調用;
componetDidUpdate(nextProps,nextState),在組件完成更新后立即調用,不初始化時不會被調用;
?
卸載組件觸發:
componentWillUnmount,在組件從dom中移除時立刻被調用;
?
例:
構造2個組件,在子組件Sub中加入所有生命周期函數;
import React from 'react';
import Reactdom from 'react-dom';
?
class Sub extends React.Component {
? constructor(props) {
??? console.log(props);
??? super(props);
??? this.state = {count:0};
? }
?
? handleClick(event) {
??? this.setState({count: this.state.count + 1});
? }
?
? render() {
??? console.log('Sub render');
??? return (<div id='sub' onClick={this.handleClick.bind(this)}>
????? Sub's count = {this.state.count}
??? </div>);
? }
?
? componentWillMount() {?? //constructor之后,第1次render之前
??? console.log('Sub componentWillMount');
? }
?
? componentDidMount() {?? //第1次render之后
??? console.log('Sub componentDidMount');
? }
?
? componentWillUnmount() {?? //清理工作
??? console.log('Sub componentWillUnmount');
? }
}
?
class Root extends React.Component {
? constructor(props) {
??? super(props);
??? console.log('Root construtor');
??? this.state = {};
? }
?
? render() {
??? return (<div>
????? <Sub />
??? </div>);
? }
}
?
Reactdom.render(<Root />, document.getElementById('root'));
?
例,增加更新組件函數:
import React from 'react';
import Reactdom from 'react-dom';
?
class Sub extends React.Component {
? constructor(props) {
??? console.log(props);
??? super(props);
??? this.state = {count:0};
? }
?
? handleClick(event) {
??? this.setState({count: this.state.count + 1});
? }
?
? render() {
??? console.log('Sub render');
??? return (<div id='sub' onClick={this.handleClick.bind(this)}>
????? Sub's count = {this.state.count}
??? </div>);
? }
?
? componentWillMount() {?? //第1次render之前
??? console.log('Sub componentWillMount');
? }
?
? componentDidMount() {?? //第1次render之后
??? console.log('Sub componentDidMount');
? }
?
? componentWillReceiveProps(nextProps) {?? //props變更時接到新props了,交給shouldComponentUpdate;props組件內只讀,只能從外部改變
??? console.log(this.props);
??? console.log(nextProps);
??? console.log('Sub componentWillReceiveProps', this.state.count);
? }
?
? shouldComponentUpdate(nextProps, nextState) {?? //是否組件更新,props或state發生改變時,返回布爾值,true才會更新
??? console.log('Sub shouldComponentUpdate', this.state.count, nextState);
??? return true;?? //return false將攔截更新
? }
?
? componentWillUpdate(nextProps, nextState) {?? //同意更新后,真正更新值,之后調用render
??? console.log('Sub componentWillUpdate', this.state.count, nextState);
? }
?
? componentDidUpdate(prevProps, prevState) {?? //同意更新后,真正更新后,在render之后調用
??? console.log('Sub componentDidUpdate', this.state.count, prevState);
? }
?
? componentWillUnmount() {?? //清理工作
??? console.log('Sub componentWillUnmount');
? }
}
?
class Root extends React.Component {
? constructor(props) {
??? super(props);
??? console.log('Root construtor');
??? this.state = {
????? flag:true,
????? name:'root'
??? };
? }
?
? handleClick(event) {
??? this.setState({
????? flag: !this.state.flag,
????? name:this.state.flag?this.state.name.toLowerCase():this.state.name.toUpperCase()
??? });
? }
?
? render() {
??? return (<div id='root' onClick={this.handleClick.bind(this)}>
????? my name is {this.state.name} <hr />
????? <Sub />?? //父組件的render,會引起下一級組件的更新,導致props重新發送,即使子組件props沒有改變過
??? </div>);
? }
}
?
Reactdom.render(<Root />, document.getElementById('root'));
調整瀏覽器窗口,會引起重繪;
?
?
也叫函數式組件;
組件,默認是有狀態組件;
React從15.0開始支持無狀態組件;
開發中,很多情況下,組件不需要state狀態,也不需要生命周期函數,無狀態組件很好地滿足了需要;
無狀態組件函數應提供一個參數props,返回一個React元素;
無狀態組件函數本身就是一個render函數;
?
例:
import React from 'react';
import ReactDom from 'react-dom';
?
// function Root(props) {
//?? return (<div>
//??? ?my name is {props.name}
//?? </div>)
// }
?
let Root = props => <div>my name is {props.name}</div>;?? //箭頭函數形式
?
ReactDom.render(<Root name='magedu'/>, document.getElementById('root'));
?
?
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。