手挽手带你学React:二档 React生命周期以及组件开辟

手挽手带你学React入门二档,组件开辟的最先,合理应用生命周期和组件,能够让你的开辟变地流畅又happy,这篇文章带你学会建立组件,应用组建。学起来吧!

React 组件生命周期

进修React,生命周期很主要,我们相识完生命周期的各个组件,对写高机能组件会有很大的协助.
我们先来看一张图

《手挽手带你学React:二档 React生命周期以及组件开辟》

组件初始化的时刻

1、getDefaultProps()

设置默许的props,也能够用dufaultProps设置组件的默许属性.

2、getInitialState()

在运用es6的class语法时是没有这个钩子函数的,能够直接在constructor中定义this.state。此时能够接见this.props

3、componentWillMount()( 谢谢原罪大神: 此声明周期在react16已被烧毁,到17直接删除)

组件初始化时只挪用,今后组件更新不挪用,全部生命周期只挪用一次,此时能够修正state。

4、 render()

react最主要的步骤,建立假造dom,举行diff算法,更新dom树都在此举行。此时就不能变动state了。

5、componentDidMount()

组件衬着以后挪用,只挪用一次。

组件更新的时刻
6、componentWillReceiveProps(nextProps)( 谢谢原罪大神: 此声明周期在react16已被烧毁,到17直接删除)

组件初始化时不挪用,组件吸收新的props时挪用。

7、shouldComponentUpdate(nextProps, nextState)

react机能优化异常主要的一环。组件吸收新的state或许props时挪用,我们能够设置在此对照前后两个props和state是不是雷同,假如雷同则返回false阻挠更新,由于雷同的属性状况一定会天生雷同的dom树,如许就不需要制造新的dom树和旧的dom树举行diff算法对照,勤俭大批机能,尤其是在dom构造庞杂的时刻

8、componentWillUpdate(nextProps, nextState)

组件初始化时不挪用,只要在组件将要更新时才挪用,此时能够修正state,render 的时刻会用你变动的值,然则这内里不能挪用 this.setState(),会让你堕入死轮回

9、render()

组件衬着

10、componentDidUpdate()

组件初始化时不挪用,组件更新完成后挪用,此时能够猎取dom节点。

组件卸载的时刻

11、componentWillUnmount()

组件将要卸载时挪用,一些事宜监听和定时器需要在此时消灭。


// 在我们组件第一次加载完的时刻会如许实行生命周期
export default class App extends Component {
    constructor(){
        super()
        this.state={
        
        }
    }

    // getDefaultProps(){
    // es6 不支持这个
    // console.log('1.实行getDefaultProps')
    // 详细用法在下面
    // }
    
    // getInitialState(){
    // es6里不用它了
    // console.log('2.实行getInitialState')
    // 这个实际上是上面的state 在 constructor完成
    // }
    componentWillMount(){
        console.log('3.实行componentWillMount')
    }
    render() {
        console.log('4.实行render')
        return (
            
        )
    }
    componentDidMount(){
        console.log('5.实行componentWillMount')

    }
}

// 接 getDefaultProps
// 在ES6里这么玩

// 另有一种弄法是ES7内里的
// static defaultProps = {
 //     name: 'demo'
 // };  这里我们不多讲了。。讲多了该晕了 感兴趣的加我微信 shouzi_1994
App.defaultProps = {
    name: 'demo'
};

// 在我们组件更新的时刻我们举行以下生命周期
export default class App extends Component {
    constructor(){
        super()
        this.state={
            name:'test'
        }
    }
    componentWillReceiveProps(nextProps){
        // props 更新的时刻挪用
        console.log('1.实行componentWillReceiveProps')
    }
    shouldComponentUpdate(nextProps, nextState){
        console.log('2.实行shouldComponentUpdate')
        // 这个需要着重强调,我们优化机能用它很主要!假如我们行将更新的东西和本来的数据雷同,return一个false就住手组件更新勤俭机能
        if(nextState.name == this.state.name){
            return false
        }else{
            return true
        }
    }
    componentWillMount(nextProps, nextState){
        // 在组件衬着前 挪用这个
        console.log('3.实行componentWillMount')
    }
    change=()=>{
        this.setState({name:'QM'})
    }
    render() {
        console.log('4.实行render')
        return (
            <button onClick={this.change}>测试</button>
        )
    }
   componentDidUpdate(){
        console.log('5.实行componentDidUpdate')       
   }
   componentWillUnmount(){
    //    这个在卸载的时刻会挪用 营业逻辑写内里就好了 
   }
}

生命周期简朴引见就这些了,真正事情中要根据营业需求来挪用,大大增添你的开辟效力,处置惩罚你开辟中碰到的困难。

组件建立

实在我们前面的App实际上就是一个组件了,我们类比到vue内里,它就是脚手架为我们建立的App.vue 是一个根组件,我们别的组件都衬着到这个组件的内部就好了。

那末 我们怎样建立一个子组件呢?

export default class App extends Component {
    constructor(){
        super()
        this.state={
        
        }
    }
  
    render() {
        //要想运用子组件也很简朴 用标签的情势拿进来就好了
        return (
            <Children />
        )
    }
  
}

//下面我们再写一个class 而且继续 Component 这就是一个组件了

class Children extends Component{
    constructor(){
        super()
        this.state={
        
        }
    }
    render(){
        return(
            <h1>我是子组件</h1>
        )
    }
}

组件传参

我们学会了怎样建立组件,那末组件怎样传参呢?这个是异常主要的东西,毕竟组件之间不能通信,那就没有建立它的意义了。

父子传参

在React中父子传参极为相似Vue 直接在标签上填写属性,然则在子组件吸收的时刻会有所不同

我们接着运用上面的代码

export default class App extends Component {
    constructor(){
        super()
        this.state={
        
        }
    }
  
    render() {
        //要想运用子组件也很简朴 用标签的情势拿进来就好了
        return (
            <Children params={"我从父组件传过来"}/>
        )
    }
  
}

//下面我们再写一个class 而且继续 Component 这就是一个组件了

class Children extends Component{
    constructor(){
        super()
        this.state={
        
        }
    }
    // 经由过程这类情势 我们就能够把父组件的东西通报给子组件了,一切的属性存储在props内里,上面我们引见生命周期的时刻,也提了一下怎样建立默许props。这里我们写一下

    render(){
        return(
            <div>
                <h1>我是子组件</h1>
                <h2>{this.props.params}</h2>
            </div>
        )
    }
    // 假如父组件没有通报 params 我们又想运用默许的props 那末就要运用下面的写法
}

Children.defaultProps = {
    params: '我是默许的东西'
};

// 设置了默许props今后 假如我们不传参就会默许展现我们默许规定好的属性了

插槽(相似Vue solt)
为何要把插槽放在这里解说呢?实际上React的插槽是经由过程传参的情势下来的,怎样明白呢?我以为放进代码中是最轻易明白的。

export default class App extends Component {
    constructor(){
        super()
        this.state={
        
        }
    }
  
    render() {
        //要想运用子组件也很简朴 用标签的情势拿进来就好了
        return (
            <Children params={"我从父组件传过来"}>
                <div>通报第一个</div>
                <div>通报第二个</div>
                <div>通报第三个</div>
            </Children>
        )
    }
  
}

//下面我们再写一个class 而且继续 Component 这就是一个组件了

class Children extends Component{
    constructor(){
        super()
        this.state={
        
        }
    }
    // 经由过程这类情势 我们就能够把父组件的东西通报给子组件了,一切的属性存储在props内里,上面我们引见生命周期的时刻,也提了一下怎样建立默许props。这里我们写一下

    render(){
        console.log(this.props)
        // {children:Array(3)
        // params:"我从父组件传过来"}


        // children的内容为 [
            // {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …},
            // {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …},
            // {$$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: {…}, …}
            // ]
        //我们能够看到 他们被递次放到了 this.props.children中 而且 这是个数组 内部存储的就是假造dom
        
        return(
            <div>
                <h1>我是子组件</h1>
                {/* 这里我用轮回的体式格局把三个children取出来直接衬着即可 */}
                {this.props.children.map((item,key)=>{
                    return item
                })}
                {/* 我们越发直观一点 */}
                {this.props.children[1]}
                {this.props.children[0]}
                {this.props.children[2]}
                 {/* 看到这里人人应当能够晓得插槽的简朴用法了吧 */}
            </div>
        )
    }
    // 假如父组件没有通报 params 我们又想运用默许的props 那末就要运用下面的写法
}

Children.defaultProps = {
    params: '我是默许的东西'
};

子传父参
在Vue中我们能够经由过程定义函数,以实参的情势通报,在父组件捕捉的情势来猎取想要通报的参数,那末在React中这个要领是不是也一样实用呢?答案是一定的,依旧是经由过程父组件声明函数,通报给子组件,子组件挪用并传入参数,在父组件捕捉即可。

export default class App extends Component {
    constructor(){
        super()
        this.state={
            myPatams:"test"
        }
    }
    getParams(params){
        console.log(params,this)
        this.setState({
            myPatams:params
        })
    }
    render() {
        //要想运用子组件也很简朴 用标签的情势拿进来就好了
        return (
            <div>    
                {this.state.myPatams}
                <Children params={"我从父组件传过来"} getParams={this.getParams.bind(this)}></Children>
                {/* 这里我们把函数通报下去,一定要bind this 否则在我们在子组件中运用bind来挪用的时刻,this的指向会跑到子组件中 我们拿到的参数意义就不大了 固然箭头函数也是完整没题目的 */}
            </div>
        )
    }
  
}

//下面我们再写一个class 而且继续 Component 这就是一个组件了

class Children extends Component{
    constructor(){
        super()
        this.state={
        
        }
    }
    render(){

        return(
            <div>
                <h1>我是子组件</h1>
                <button onClick={this.props.getParams.bind(this,"我是子传过来的参数")}>子传父参</button>
                {/* 我们在这里挪用父组件通报过来的要领,而且传入参数 */}
            </div>
        )
    }
}

Children.defaultProps = {
    params: '我是默许的东西'
};

非父非子传参(events 要领)
这类非关联型组件传参平常运用redux来传参,这里我们另有没进修到,我们借助node的EventEmitter也能够轻松完成

import React,{Component} from 'react'
// 起首我们建立一个监听器
import EventEmitter from 'events'; //事宜监控对象
let emitter = new EventEmitter; //建立一个事宜监控者 一般级别的监听
emitter.setMaxListeners(100000); //设置监控管理器的最大监听数目
export default class App extends Component {
    constructor(){
        super()
        this.state={
            myPatams:"test"
        }
    }
    getParams(params){
        console.log(params,this)
        this.setState({
            myPatams:params
        })
    }
    render() {
        //要想运用子组件也很简朴 用标签的情势拿进来就好了
        return (
            <div>    
                {this.state.myPatams}
                <Children params={"我从父组件传过来"} getParams={this.getParams.bind(this)}></Children>
                {/* 这里我们把函数通报下去,一定要bind this 否则在我们在子组件中运用bind来挪用的时刻,this的指向会跑到子组件中 我们拿到的参数意义就不大了 固然箭头函数也是完整没题目的 */}
                <ChildrenTwo />
            </div>
        )
    }
  
}

//下面我们再写一个class 而且继续 Component 这就是一个组件了

class Children extends Component{
    constructor(){
        super()
        this.state={
            emit:""
        }
    }
    componentWillMount(){
        emitter.on('childrenEmit',(param)=>{  //我们在这里设置监听
            console.log(param)
            this.setState({
                emit:param
            })
        })
    }
    render(){

        return(
            <div>
                <h1>{this.state.emit}</h1>
                <button onClick={this.props.getParams.bind(this,"我是子传过来的参数")}>子传父参</button>
                {/* 我们在这里挪用父组件通报过来的要领,而且传入参数 */}
            </div>
        )
    }
}

class ChildrenTwo extends Component{
    constructor(){
        super()
        this.state={
        
        }
    }
    gaveParams(param){
        emitter.emit('childrenEmit',param)  //从第二个子组件触发而且通报参数
    }
    render(){

        return(
            <div>
                <h1>我是子组件</h1>
                <button onClick={this.gaveParams.bind(this,"我是ChildrenTwo传过来的参数")}>非父非子传参</button>
            </div>
        )
    }
}


组件抽离

写了这么多,置信人人差不多会写本身的组件而且在组件中通报参数了,这里另有一个题目,人人是不是是发明我的一切组件都写在了一个JS内部,如许假如是一个大项目,我们的这个JS就会变地异常痴肥,这时刻我们就要抽离这个组件。实际上异常简朴,用到的就是我们ES6的 export 导出 即可 假如只要一个组件 那末 还能够像我们誊写App这个基本组件一样 运用 export default 默许导出

这里我给人人抽离一下

// App.js
import React,{Component} from 'react'
import {Children} from './components/Children.js'  // 由于我们的Children中运用的是 export 来暴露

//import Children from './components/Children.js' //  假如运用的是 export default 则应当如许写

export default class App extends Component {
    constructor(){
        super()
        this.state={
            myPatams:"test"
        }
    }
    getParams(params){
        console.log(params,this)
        this.setState({
            myPatams:params
        })
    }
    render() {
        //要想运用子组件也很简朴 用标签的情势拿进来就好了
        return (
            <div>    
                {this.state.myPatams}
                <Children params={"我从父组件传过来"} getParams={this.getParams.bind(this)}></Children>
                {/* 这里我们把函数通报下去,一定要bind this 否则在我们在子组件中运用bind来挪用的时刻,this的指向会跑到子组件中 我们拿到的参数意义就不大了 固然箭头函数也是完整没题目的 */}
            </div>
        )
    }
  
}
// children.js
import React,{Component} from 'react'

// 当我们抽离出来今后 必需要再次引入 react的必要组件

export class Children extends Component{  //我们这里运用的是export来暴露  假如只要一个组件 也能够运用 export default 来暴露
    constructor(){
        super()
        this.state={
        
        }
    }
    render(){

        return(
            <div>
                <h1>我是子组件</h1>
                <button onClick={this.props.getParams.bind(this,"我是子传过来的参数")}>子传父参</button>
                {/* 我们在这里挪用父组件通报过来的要领,而且传入参数 */}
            </div>
        )
    }
}

Children.defaultProps = {
    params: '我是默许的东西'
};

功德圆满了 代码是不是是清楚多了??

总结

这一期内容不多 主如果引见组件的生命周期 运用要领 以及怎样传参,这些内容可全都是干货,事情中会常常常常运用到,愿望人人能本身写小demo来熟习一下写法,下一期将会带人人进修React-Router 以及context和高阶组件的建立,为我们进修Redux打下基本

视频制造中

    原文作者:蒋吉兆
    原文地址: https://segmentfault.com/a/1190000018139569
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞