React类组件

时间:2021-1-8 作者:admin

一 ES6创建方式

import React from 'react';

class App extends React.Component{
    constructor(props) {
        super(props);
        this.state={n:1}
    }
    add=()=>{
        this.setState((state)=>{
            return {n:state.n+1}
        },()=>{
            //打印的是更新后的state
            console.log('回调'+this.state.n);
        })
        //打印的是旧的state
        console.log('立即'+this.state.n);
    }
    render(){
        return (
            <div>
                <div>{this.state.n}
                    <button onClick={this.add}>加一</button>
                </div>
                <B name={this.state.n} />
            </div>
        )
    }
}
class B extends React.Component{
    // componentWillReceiveProps(nextProps, nextContext) {
    //     console.log('旧的'+this.props.name);
    //     console.log('更新了');
    //     console.log('新的'+nextProps.name);
    // }

    render() {
        return(
            <div>{this.props.name}</div>
        )
    }
}

二 props

  1. props的作用
   (1) 接收外部数据
         只能读不能写,外部数据由父组件传递。
   (2) 接收外部函数
         在恰当的时机,调用该函数。该函数一般是父组件的函数。
  1. 读props,构造函数中写了super(props)之后,this.props就是外部数据对象的地址了,直接使用this.props.x就可以访问x属性了。
  2. 当接收props变化时,会触发componentWillReceiveProps钩子,该钩子已被弃用。

三 state

    //初始化
    this.state={n:1}
    //读state
    this.state.n
    //写
    this.setState(newState,fn)或this.setState((state,props)=>newState,fn)
    //setState不会立即改变this.state,会在当前代码执行完后,再去更新this.state,从而触发UI更新
    //setState写时会进行shallow merge,会自动将xinstate与旧state进行一级合并,而函数组件则完全不会自动合并
    //fn会在写入成功后执行

四 生命周期

  1. constructor
    //初始化state,props,以及bind this
    constructor(props){
       super(props);
    }
  1. render
    //展示视图
    //里面可以直接写if else,但不能直接写for循环,需要用到数组,例如array.map
    const add=()=>{}//写到constructor外面,并且用箭头函数,可以避免this改变的问题
    render(){
       return(
          <React.Fragment>
             <div>{n}</div>
             <div onClick={this.add}>1</div>
          </React.Fragment>
       )
    }
  1. componentDidMount
    //在元素插入页面后执行代码,这些代码依赖DOM。
    //比如想获取div的宽度就可以在这里写。
    //官方推荐,在这里发起加载数据的ajax请求
    //首次渲染会执行此钩子
    //获取div宽度
    class App extends React.Component{
    constructor(props) {
        super(props);
        this.state={n:1};
        //创建引用,下一步需要关联到div上
        this.divRef=React.createRef();
    }

    componentDidMount() {
        const {width}=this.divRef.current.getBoundingClientRect();
        console.log(width);
    }

    render(){
        return (
            <div>
                <div ref={this.divRef}>{this.state.n}
                    <button >我是按钮</button>
                </div>
            </div>
        )
    }
}
  1. shouldComponentUpdate
    //允许我们手动判断组件是否需要更新,我们可以根据应用场景灵活的设置返回值,以避免不必要的更新
    //返回true表示不阻止组件更新,返回false表示阻止组件更新
    //旧对象是{n:1},新对象也是{n:1},
    //但由于这两个对象地址不同,因此React认为数据不同数据变了,
    //从而需要重新render,对比新虚拟DOM和上次虚拟DOM的不同,
    //虽然对比结果是值相同不需要更新UI,但还是多了执行render和对比DOM的过程。
    //因此我们可以使用shouldComponentUpdate,手动判断
    class App extends React.Component{
    constructor(props) {
        super(props);
        this.state={n:1};
    }

    add=()=>{
        this.setState(state=>({n:state.n+1}));
        this.setState(state=>({n:state.n-1}));
    }

    shouldComponentUpdate(newProps,newState){
        if(newState.n===this.state.n){
            return false;
        }else{
            return true;
        }
    }

    render(){
        console.log('渲染了')
        return (
            <div>
                <div>{this.state.n}
                    <button onClick={this.add}>我是按钮</button>
                </div>
            </div>
        )
    }
}
    //React.PureComponent可以代替React.Component
    //它会在 render 之前对比新 state 和旧 state 的每一个 key,以及新 props 和旧 props 的每一个 key。
    //如果所有 key 的值全都一样,就不会 render;如果有任何一个 key 的值不同,就会 render。
  1. componentDidUpdate
    //在视图更新后执行代码
    //此处也可以发起ajax请求,用于更新数据
    //比如userID变了,需要获取新的数据,就要在componentDidUpdate里面发起ajax请求。
    //首次渲染不会执行此钩子
    //在此处setState可能会引起无限循环,除非添加if条件判断
    //若shouldComponentUpdate返回false,则不会触发此钩子
  1. componentWillUnmount
    //组件将要被移除页面然后被销毁时执行的代码
    //unmount过的组件不会再次mount
    //在unmount之前,监听的时间,创建的Timer,AJAX请求都要取消
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。