React組件-事件、狀態和生命週期

組件狀態

事件  

(事件名大寫json

注意:組件事件須要配合狀態,因此如今沒法呈現效果bash

class Cmp1 extends React.Component{
    constructor(...args){
        super(..args);
        this.a=0;//要用狀態,屬性不行,props也不行
    }
    add(){
        this.a++;
        //這個函數會執行,a也會變,可是不會從新渲染
        alert(this.a);
    }
    render(){
        return <div>
            //強制綁定add的this
            <input type="button" value="加1" onClick={this.add.bind(this)} />
        </div>
    }
} 

複製代碼

a其實變了,可是隻有狀態改變能引起從新渲染

狀態

組件的狀態很是有用函數

  • 屬性是隻讀,狀態是可變的
  • 狀態改變,組件會從新渲染(父級屬性變化,強制刷新也能夠引發從新渲染)
    • 引發組件從新渲染的條件
      • state
      • props
      • 強制渲染.   this.forceUpdate()

class Cmp1 entends React.Component{
    constructor(...args){
        super(...args);
        //狀態初始化
        this.state={a:0}
    }
    add(){
        //修改狀態
        this.setState({
            a:this.state.a+1
        })
    }
    render(){
        return <div>
            //強制綁定add的this
            <input type="button" value="+1" onClick={this.add.bind(this)} />
            {this.state.a}
        </div>
    }
}
let comp=<Cmp1></Cmp1>
ReactDOM.render(comp,root)複製代碼

注意⚠️:性能

  • 狀態的初始化只能放在constructor中完成
  • 必須經過setState修改狀態,不然也不能從新渲染——實際上是setState在調用render

props變化引發的從新渲染

class Parent extends React.Component{
    constructor(...args){
        super(...args);
        this.state={a:0}
    }
    render(){
        return <div>
            <input type="button" value="+1" onClick={function(){
                this.setState({
                    a:this.state.a+1
                })
            }.bind(this)} />
            <Child a={this.state.a} />
        </div>
    }
}
class Child extends React.Component{
    constructor(...args){
        super(...args);
    }
    render(){
        return <div>
            {this.props.a}
        </div>
    }
}
複製代碼

強制渲染(forceUpdate)

class Cmp1 extends React.Component{
    constructor(.;..args){
        super(...args);
        this.a=12;
    }
    fn(){
        this.a++
        //強制渲染
        this.forceUpdate(); 
    }
    render(){
        return <div>
            <input type="button" value="+1" onClick={this.fn.bind(this)} />
            {this.a}
        </div>
    }
}
複製代碼

強制從新渲染會打亂React自身的渲染計劃,輕則影響性能,重則引起錯誤,極少使用

組件生存週期

從組件建立到銷燬的整個過程fetch


上圖中,涉及最重要的兩個鉤子函數, componentDidMount(組件已掛載)和 componentDidUpdate(組件已更新)

完整的生命週期鉤子函數

建立階段(mount)ui

  1. constructor:構造函數,這時還不算是個組件,只是class自身的初始化
  2. getDerivedStateFromProps:檢查須要更新的狀態(一個檢查函數,不是鉤子函數,檢查更新,通常不作改變)
  3. render:初始渲染
  4. componentDidMount:組件建立完成,並已掛載到DOM結構中

更新階段(update)this

  1. getDerivedStateFromProps:檢查
  2. shouldComponentUpdate:肯定組件是否須要更新  (重要)有兩個參數(nextProps,nextState)
  3. render
  4. getSnapshoutBeforeUpdate:更新前保存DOM狀態
  5. compomentDidUpdate:組件已渲染完成


阻止更新spa

shouldComponentUpdata(nextProps,nextState){
//當前狀態(變化前),新狀態(變化後)
    this.state.nextState
    //當前屬性,新屬性
    this.props.nextProps
    return true   -容許更新/。 false  -拒絕更新
}複製代碼


使用實例:阻止循環updatecode

class Parent entends React.Component{
    constructor(...args){
        super(..args);
        this.state={
            id:1
        }
    }
    next(){
        this.setState{
            id:this.state.id+1
        }
    }
    render(){
        return {
            <div>
               <input type="button" value="下一個" onClick={this.next.bind(this)}/>
               <Child id={this.state.id}/>
            </div>
        }
    }
}
class Child extends React.Component{
    constructor(..args){
        super(...args);
        this.state={
            name:'',
            age:''
        }
    }
    shouledComponentUpdata(nextProps,nextState){
        //console.log(nextProps,this.props);
        renturn{
            //條件1:屬性變了(來自父級)
            nextProps.id!=this.props.id||
            //條件2:狀態變了(來自本身)
            nextState.name!=this.state.name
        };
    }
    loadData(id){
        fetch(`data/data${id}.txt`).then(res=>{
            res.json().then(data=>{
                this.setState(data);
            });
        });
    }
    componentDidMount(){
        console.log('初始:‘,this.props.id); this.loadData(this.props.id) } componentDidUpdate(){ console.log('更新‘,this.props.id)
        this.loadData(this.props.id);
    }
    render(){
        console.log('渲染‘); return ( <div> ID:{this.props.id}<br/> 用戶名:{this.state.name},年齡:{this.state.age} </div> ) } }複製代碼

銷燬階段(Unmount)

  • componentWillUnmount:組織已銷燬
銷燬操做沒法阻止
相關文章
相關標籤/搜索