zoukankan      html  css  js  c++  java
  • 22.2、react生命周期与react脚手架(二)

    一.类:es6

    <script type="text/babel">
    class Person{
        age = 10;
        constructor(name){
            this.name = name;
            //this.age = 10;
        }
        getName(){
            return this.name;
        }
        getAge(){
            return this.age;
        }
    }
    let p = new Person("aaa");
    console.log(p.getName());
    console.log(p.getAge());
    </script>
    

    res:
    image

    二.生命周期函数

    组件生命周期概述

    1.初始化

    在组件初始化阶段会执行

    1. constructor
    2. static getDerivedStateFromProps()
    3. componentWillMount() / UNSAFE_componentWillMount()
    4. render()
    5. componentDidMount()
    2.更新阶段

    props或state的改变可能会引起组件的更新,组件重新渲染的过程中会调用

    以下方法:

    1. componentWillReceiveProps() / UNSAFE_componentWillReceiveProps()
    2. static getDerivedStateFromProps()
    3. shouldComponentUpdate()
    4. componentWillUpdate() / UNSAFE_componentWillUpdate()
    5. render()
    6. getSnapshotBeforeUpdate()
    7. componentDidUpdate()
    3.卸载阶段

    componentWillUnmount()

    4.错误处理

    componentDidCatch() 同Vue的错误函数
    子级不能捕获自己的错误,只能父级捕获子级的错误 —— 冒泡

    参考文献:

    https://reactjs.org/docs/react-component.html

    https://blog.csdn.net/qq_29311407/article/details/79861522

    image

    constructor init
    react vue
    componentWillMount beforeMount
    componentDidMount mounted
    componentWillUpdate beforeUpdate
    componentDidUpdate updated
    render 渲染
    componentWillUnmount beforeDistory
    没有componentDidlUnmount distoryed
    componentWillReceiveProps(props,state)组件属性更新 —— 状态不会监听
    UNSAFE_componentWillReceiveProps(nextProps)
    shouldComponentUpdate(nextProps, nextState) 组件属性和状态更新
    react                            vue
    componentWillMount   =      beforeMount
    componentDidMount    =      mounted
    
    componentWillUpdate     =      beforeUpdate
    componentDidUpdate      =      updated
    
    render  渲染
    
    componentWillUnmount     =     beforeDistory
    没有componentDidlUnmount  =    distoryed
    
    componentWillReceiveProps(props,state)  组件属性更新 —— 状态不会监听 
    
    UNSAFE_componentWillReceiveProps(nextProps)
    
    shouldComponentUpdate(nextProps, nextState)      组件属性和状态更新
    

    顺序:

    1.初始化

    1、constructor
    2、componentWillMount(即将被淘汰的方法)、UNSAFE_componentWillMount
    (顺序:先执行componentWillMount再执行UNSAFE_componentWillMount)
    3、render
    4、componentDidMount
    5、ReactDom.render(1,2,fn);

    2.更新的顺序:

    属性更新、状态更新

    1.1 componentWillReceiveProps 属性
    1.2 shouldComponentUpdate 状态
    —————— 特别: 有返回值 true/false
               true继续往下执行
               false终止渲染

    2、componentWillMount
    3、render
    4、componentDidMount

    componentWillUpdate 消失 ==>替患者 UNSAFE_componentWillUpdate

    3.销毁:释放资源   比如定时器 对象置空null

    componentWillUnmount
    1、通过原生删除节点的方式不会触发钩子函数
    2、必须用过react自身的方式进行释放
    ReactDOM.unmountComponentAtNode(container)
    切换组件

    案例:

    exp1:

    <script type="text/babel">
    class Test extends React.Component{
        constructor(...args){
            super(...args);
            this.state = {a:12,b:5};
            //初始化 属性 和数据 内部的属性和函数 只会调用一次
            console.log("init constructor",this.state,this.props);
        } 
        
        componentWillMount(){
            //原生dom 渲染之前 做数据交换
            console.log("componentWillMount",this.state,this.props);
        }
        componentDidMount(){
            //挂载中 写入页面的dom
            console.log("componentDidMount"); 
        }
    
        render(){
            //正在渲染页面数据—— 虚拟dom
            console.log("render"); 
            return <div>
                生命周期
            </div>
        }
    }
    ReactDOM.render(
        <Test name="aaa"/>,
        document.getElementById("app"),
        function(){
            console.log("最终渲染完成了");//只会调用一次
        }
    );
    </script>
    

    res:
    image

    exp2:
    1.

    <script type="text/babel">
    class Test extends React.Component{
        constructor(...args){
            super(...args);
        } 
        componentWillUnmount(){
            console.log("componentWillUnmount");
        }
        distory(){
            let oApp = document.getElementById("app");
            //document.body.removeChild(oApp);
            ReactDOM.unmountComponentAtNode(oApp);
        }
    
        render(){
            //正在渲染页面数据—— 虚拟dom
            console.log("render"); 
            return <div>
                生命周期<input onClick={this.distory.bind(this)} type="button" value="销毁" />
            </div>
        }
       
    }
    ReactDOM.render(
        <Test/>,
        document.getElementById("app")
    );
    </script>
    

    res:
    image

    <script type="text/babel">
    class CompA extends React.Component{
        constructor(...args){
            super(...args);
        } 
        componentWillUnmount(){
            console.log("CompA------componentWillUnmount");
        } 
    
        render(){
            return <div>组件A </div>
        }
    }
    class CompB extends React.Component{
        constructor(...args){
            super(...args);
        } 
        componentWillUnmount(){
            console.log("CompB------componentWillUnmount");
        } 
    
        render(){
            return <div>组件B </div>
        }
    }
    let i = 0;
    document.onclick = function(){
        i++;
        ReactDOM.render(
            i%2==0?<CompA/>:<CompB/>,
            document.getElementById("app")
        );
    };
    </script>
    

    res:
    image

    exp3:

    <script type="text/babel">
    class Clock extends React.Component{
        timer = null;
        state = {a:12,iH:"00",iM:"00",iS:"00"};
    
        componentDidMount(){
            this.tick();
            this.timer = setInterval(()=>{
                this.tick();
            },1000);
        }
    
        componentWillUpdate(){
           console.log("componentWillUpdate即将更新");
        } 
        componentDidUpdate(){
            console.log("componentDidUpdate更新完成");
         } 
    
        componentWillUnmount(){
            clearInterval(this.timer);
        } 
        tick(){
            let oDate = new Date();
            this.setState({
                iH:this.addZero(oDate.getHours()),
                iM:this.addZero(oDate.getMinutes()),
                iS:this.addZero(oDate.getSeconds()),
            });
        }
        addZero(n){
            return n < 10?`0${n}`:`${n}`;
        }
       
        render(){
            console.log("render...正在渲染");
            return <div>
                <span>{this.state.iH}</span>:
                <span>{this.state.iM}</span>:
                <span>{this.state.iS}</span>
                <hr />
                <span>{this.state.a}</span>
            </div>
        }
    }
    ReactDOM.render(
        <Clock/>,
        document.getElementById("app"),
        function(){
            console.log("最终渲染完成了");//只会调用一次
        }
    );
    </script>
    

    res:
    image

    exp4:

    <script type="text/babel">
    class Parent extends React.Component{
        state = {
            name:Math.random()
        }
    
        fn(){
            this.setState({
                name:Math.random()
            });
        }
        render(){
            return <div>父组件 <input onClick={this.fn.bind(this)} type="button" value={"按钮"}/>
                <Child name={this.state.name}/>
            </div>
        }
    }
    class Child extends React.Component{
        componentWillUpdate(){
            console.log("2.componentWillUpdate即将更新");
         } 
        componentDidUpdate(){
             console.log("4.componentDidUpdate更新完成");
        }  
        componentWillReceiveProps(){
            console.log("1.1.componentWillReceiveProps组件属性更新");
        }
        shouldComponentUpdate(){
            console.log("1.2.shouldComponentUpdate组件属性和状态更新");
            return true;
        }
        render(){
            console.log("3.render...正在渲染");
            return <div>子组件——{this.props.name}</div>
        }
       
    }
    ReactDOM.render(
        <Parent />,
        document.getElementById("app"),
        function(){
            console.log("最终渲染完成了");//只会调用一次
        }
    );
    </script>
    

    res:
    image

    <script type="text/babel">
    
    class Test extends React.Component{
        state = {
            name:Math.random()
        }
    
        fn(){
            this.setState({
                name:Math.random()
            });
        }
        componentWillUpdate(){
            console.log("2.componentWillUpdate即将更新");
         } 
        componentDidUpdate(){
             console.log("4.componentDidUpdate更新完成");
        }  
        componentWillReceiveProps(){
            console.log("1.componentWillReceiveProps组件属性更新");
        }
        render(){
            console.log("3.render...正在渲染");
            return <div>{this.state.name}<input onClick={this.fn.bind(this)} type="button" value={"按钮"}/></div>
        }
       
    }
    ReactDOM.render(
        <Test />,
        document.getElementById("app")
    );
    </script>
    

    res:
    image

    <script type="text/babel">
    
    class Test extends React.Component{
        state = {
            name:Math.random()
        }
    
        fn(){
            this.setState({
                name:Math.random()
            });
        }
        componentWillUpdate(){
            console.log("2.componentWillUpdate即将更新");
         } 
        componentDidUpdate(){
             console.log("4.componentDidUpdate更新完成");
        }  
        shouldComponentUpdate(){
            console.log("1.shouldComponentUpdate组件属性和状态更新");
            return false;
        }
        render(){
            console.log("3.render...正在渲染");
            return <div>{this.state.name}<input onClick={this.fn.bind(this)} type="button" value={"按钮"}/></div>
        }
       
    }
    ReactDOM.render(
        <Test />,
        document.getElementById("app")
    );
    </script>
    

    res:
    image

    <script type="text/babel">
    class Parent extends React.Component{
        state = {
            name:Math.random()
        }
        fn(){
            this.setState({
                name:Math.random()
            });
        }
        render(){
            return <div>父组件 <input onClick={this.fn.bind(this)} type="button" value={"按钮"}/>
                <Child name={this.state.name}/>
            </div>
        }
    }
    class Child extends React.Component{ 
        state = {a:1,b:2}; 
        componentWillReceiveProps(props,state){
            console.log("1.1.componentWillReceiveProps组件属性更新",props,state);
            //在这个方法中调用setState()不会起作用,是由于他在render()前被调用
            this.setState({
                a:Math.random(),
                b:Math.random()
            });
        }
        UNSAFE_componentWillReceiveProps(props,state){
            console.log("1.1.UNSAFE_componentWillReceiveProps组件属性更新",props,state);
            //在这个方法中调用setState()不会起作用,是由于他在render()前被调用
            this.setState({
                a:Math.random(),
                b:Math.random()
            });
        } 
        shouldComponentUpdate(props,state){
            console.log("1.2.shouldComponentUpdate组件属性和状态更新",props,state);
            return true;
        }
        render(){
            return <div>子组件——{this.props.name}</div>
        }
       
    }
    ReactDOM.render(
        <Parent />,
        document.getElementById("app")
    );
    </script>
    

    res:
    image

    exp5:

    <script type="text/babel">
    class Parent extends React.Component{
        state = {
            name:Math.random()
        }
    
        fn(){
            this.setState({
                name:Math.random()
            });
        }
        render(){
            return <div>父组件 ----{this.state.name}<input onClick={this.fn.bind(this)} type="button" value={"按钮"}/>
                <Child name={this.state.name}/>
            </div>
        }
    }
    class Child extends React.Component{
        state = {
            name:this.props.name
        };
        static getDerivedStateFromProps(nextProps, prevState){
            console.log("1getDerivedStateFromProps",nextProps, prevState);
            return true;
        } 
        componentWillReceiveProps(){
            console.log("2componentWillReceiveProps");
        } 
        
        render(){
            console.log("3.render...正在渲染");
            return <div>子组件——{this.props.name}——{this.state.name}</div>
        }
       
    }
    ReactDOM.render(
        <Parent />,
        document.getElementById("app"),
        function(){
            console.log("最终渲染完成了");//只会调用一次
        }
    );
    </script>
    

    res:
    image

    exp6:

    <script type="text/babel">
    class Test extends React.Component{
        constructor(...args){
            super(...args);
            this.state = {a:12,b:5};
            //初始化 属性 和数据 内部的属性和函数 只会调用一次
            console.log("init constructor",this.state,this.props);
        } 
        UNSAFE_componentWillMount(){
            //原生dom 渲染之前 做数据交换
            console.log("UNSAFE_componentWillMount",this.state,this.props);
        }
        componentWillMount(){
            //原生dom 渲染之前 做数据交换
            console.log("componentWillMount",this.state,this.props);
        }
        
        componentDidMount(){
            //挂载中 写入页面的dom
            console.log("componentDidMount"); 
        }
    
        render(){
            //正在渲染页面数据—— 虚拟dom
            console.log("render"); 
            return <div>
                生命周期
            </div>
        }
       
    }
    ReactDOM.render(
        <Test name="aaa"/>,
        document.getElementById("app"),
        function(){
            console.log("最终渲染完成了");//只会调用一次
        }
    );
    </script>
    

    res:
    image

    exp7:

    <script type="text/babel">
    class Parent extends React.Component{
        state = {
            name:Math.random()
        }
    
        fn(){
            this.setState({
                name:Math.random()
            });
        }
        render(){
            return <div>父组件 <input onClick={this.fn.bind(this)} type="button" value={"按钮"}/>
                <Child name={this.state.name}/>
            </div>
        }
    }
    class Child extends React.Component{
    
        //UNSAFE_componentWillReceiveProps用来替代componentWillReceiveProps
        componentWillReceiveProps(){
            console.log("1.1.componentWillReceiveProps组件属性更新");
        }
        UNSAFE_componentWillReceiveProps(){
            console.log("1.2.UNSAFE_componentWillReceiveProps组件属性和状态更新");
        }
        render(){
            console.log("3.render...正在渲染");
            return <div>子组件——{this.props.name}</div>
        }
       
    }
    ReactDOM.render(
        <Parent />,
        document.getElementById("app"),
        function(){
            console.log("最终渲染完成了");//只会调用一次
        }
    );
    </script>
    

    res:
    image

    exp8:

    <script type="text/babel">
    class Parent extends React.Component{
        //throw new Error("parent");
        state = {
            name:Math.random()
        }
    
        fn(){
            this.setState({
                name:Math.random()
            });
        }
    
        componentDidCatch(){
            console.log("Parent ----- componentDidCatch");
        } 
        render(){
            return <div>父组件 <input onClick={this.fn.bind(this)} type="button" value={"按钮"}/>
                <Child name={this.state.name}/>
            </div>
        }
    }
    class Child extends React.Component{
        //throw new Error("child");
        componentDidCatch(){
            console.log("child ----- componentDidCatch");
        } 
        render(){
            throw new Error("child");
            console.log("3.render...正在渲染");
            return <div>子组件——{this.props.name}</div>
        }
       
    }
    ReactDOM.render(
        <Parent />,
        document.getElementById("app"),
        function(){
            console.log("最终渲染完成了");//只会调用一次
        }
    );
    </script>
    

    res:
    image


    创建reactapp

    方法一、  npx create-react-app myreact

    方法二、 1. cnpm i -g create-react-app
         2. create-react-app myreact

    cd myreact
    npm start


    vue-cli:

    1、vue-cli2.x vue init webpack myvue
    2、vue-cli3.x vue create myvue —— vue.config.js

    入口文件:main.js

    静态文件:vue-cli2.x   static/
           vue-cli3.x   public/

    组件:  .vue   template/script/style

    react:

      cnpm i -g create-react-app
      create-react-app myreact

    入口文件:index.js

    静态文件:public/

    组件: .js .css

    import "./xxx.css"

    image


    react 安装:react, react-dom, and react-scripts —— 后台

    webpack/babel...

    %PUBLIC_URL%/---> public/


    改端口
    两种方法:

    1、myreact ode_modules eact-scriptsscriptsstart.js

    2、工程文件 package.json

    "start": "set port=8888 && react-scripts start",
    

    要新建两个目录:

    1、components

    2、assets
        静态文件—— 文件会打包


    路由: cnpm i -S react-router-dom

    https://reacttraining.com/ 官网 http://reacttraining.cn/

    http://react-china.org/t/react-router4/15843

    http://react-guide.github.io/react-router-cn/docs/API.html

    http://react-guide.github.io/react-router-cn/


    jsonp:

    http://api.douban.com/v2/movie/in_theaters?callback=xxx&city=北京

    subjects

    jQuery的ajax没有跨域功能 集成jsonp

    exp1:

    <script type="text/babel">
    class MoveBox extends React.Component{
        state = {
            id:1,
            city:"北京"
        }
        /*//第二种
        shouldComponentUpdate(nextProps, nextState){
            console.log(2222,this.state, nextState);
            return true;
        }**/
    
        fn(data){
            //第三种
            console.log("fn",this.state, data);
            if(this.state.city == data.city)return;
            this.setState({
                id : data.id,
                city:data.city
            });
        }
    
        render(){
            return <div>
    
                {
                    this.props.arr.map(item=><input 
                    className={this.state.id==item.id?"active":""} 
                    key={item.id} 
                    type="button" 
                    onClick={this.fn.bind(this,item)}
                    value={item.city}/>)
                }
    
                <BoxList city={this.state.city}/>
                
            </div>
        }
    }
    class BoxList extends React.Component{
        state = {
            movies:[]
        };
        componentDidMount(){
            this.getMovies();
        }
        /*
        shouldComponentUpdate(nextProps, nextState){
            console.log(111,nextProps, nextState);
            return true;
        }*/
    
        UNSAFE_componentWillReceiveProps(props){
            /*方法1
            console.log(props,this.props);
            if(props.city == this.props.city)return;
            */
            this.getMovies();
        }
    
        getMovies(){
            $.ajax({
                url:"http://api.douban.com/v2/movie/in_theaters",
                data:{
                    city:this.props.city
                },
                dataType:"jsonp",
                success:(res)=>{
                    console.log(res);
                    this.setState({
                        movies:res.subjects
                    });
    
                }
            });
        }
        render(){
            return <ul>
               {
                this.state.movies.map(item=><li key={item.id}>{item.title}</li>)
    
               }
            </ul>
        }
    }
    
    let arr = [
        {id:1,city:"北京"},
        {id:2,city:"上海"},
        {id:3,city:"深圳"},
        {id:4,city:"青岛"}
    ];
    
    
    ReactDOM.render(
        <MoveBox arr={arr} />,
        $("#app")[0]
    );
    </script>
    

    image

    exp2:

    <script type="text/babel">
    class MoveBox extends React.Component{
        state = {...this.props.arr[0]};
        fn(data){
    
            console.log(this);
            //第三种
            //console.log("fn",this.state, data);
            if(this.state.city == data.city)return;
            this.setState({
                id : data.id,
                city:data.city
            });
        }
        render(){// 
            return <div>
                {/*
                    this.props.arr.map(item=><input 
                    className={this.state.id==item.id?"active":""} 
                    key={item.id} 
                    type="button" 
                    onClick={this.fn.bind(this,item)}
                    value={item.city}/>)
                }
                */}
                <BoxTitle arr={this.props.arr} parent={this} fn={this.fn} />
                <BoxList city={this.state.city}/>
                
            </div>
        }
    }
    
    class BoxTitle extends React.Component{
        state = {...this.props.arr[0]}
    
        render(){
            return <div>
                {
                    this.props.arr.map(item=><input 
                    className={this.state.id==item.id?"active":""} 
                    key={item.id} 
                    type="button" 
                    onClick={this.props.fn.bind(this.props.parent,item)}
                    value={item.city}/>)
                }
            </div>
        }
    }
    class BoxList extends React.Component{
        state = {
            movies:[]
        };
        componentDidMount(){
            this.getMovies();
        }
    
        UNSAFE_componentWillReceiveProps(props){
            this.getMovies();
        }
        getMovies(){
            $.ajax({
                url:"http://api.douban.com/v2/movie/in_theaters",
                data:{
                    city:this.props.city
                },
                dataType:"jsonp",
                success:(res)=>{
                    console.log(res);
                    this.setState({
                        movies:res.subjects
                    });
                }
            });
        }
        render(){
            return <ul>
               {
                this.state.movies.map(item=><li key={item.id}>{item.title}</li>)
               }
            </ul>
        }
    }
    
    let arr = [
        {id:1,city:"北京"},
        {id:2,city:"上海"},
        {id:3,city:"深圳"},
        {id:4,city:"青岛"}
    ];
    ReactDOM.render(
        <MoveBox arr={arr} />,
        $("#app")[0]
    );
    </script>
    

    res:
    image

    https://reactjs.org/docs/react-component.html#defaultprops

  • 相关阅读:
    TortoiseSVN 命令 (命令行执行工具)(转)
    express blend下载
    js绝对地址图片转换成base64的方法
    js判断是否安装flash player及当前版本 和 检查flash版本是否需要升级
    js实现默认或者触发一个事件选中元素内容的方法
    js实现复制功能,将需要复制的内容放入剪切板上
    前端js上传文件插件
    javascript检测浏览器的缩放状态实现代码 是指浏览器网页内容的百分比缩放(按Ctrl和+号键或者-号键的缩放)
    html5 canvas 画图移动端出现锯齿毛边的解决方法
    jquery实现全选/反选功能
  • 原文地址:https://www.cnblogs.com/zhongchao666/p/9463048.html
Copyright © 2011-2022 走看看