从零开始学React:二档 React生命周期以及组件开发

手挽手带你学React入门二档,组件开发的开始,合理运用生命周期和组件,可以让你的开发变地流利又happy,这篇文章带你学会建立组件,运用组建。学起来吧!javascript

视频教程

React 组件生命周期

学习React,生命周期很重要,咱们了解完生命周期的各个组件,对写高性能组件会有很大的帮助. 咱们先来看一张图vue

组件初始化的时候java

一、getDefaultProps()node

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

二、getInitialState()es6

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

三、componentWillMount()redux

组件初始化时只调用,之后组件更新不调用,整个生命周期只调用一次,此时能够修改state。数组

四、 render()性能优化

react最重要的步骤,建立虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。

五、componentDidMount()

组件渲染以后调用,只调用一次。

组件更新的时候 六、componentWillReceiveProps(nextProps)

组件初始化时不调用,组件接受新的props时调用。

七、shouldComponentUpdate(nextProps, nextState)

react性能优化很是重要的一环。组件接受新的state或者props时调用,咱们能够设置在此对比先后两个props和state是否相同,若是相同则返回false阻止更新,由于相同的属性状态必定会生成相同的dom树,这样就不须要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤为是在dom结构复杂的时候

八、componentWillUpdata(nextProps, nextState)

组件初始化时不调用,只有在组件将要更新时才调用,此时能够修改state,render 的时候会用你更改的值,可是这里面不能调用 this.setState(),会让你陷入死循环

九、render()

组件渲染

十、componentDidUpdate()

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

组件卸载的时候

十一、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打下基础

视频制做中

相关文章
相关标签/搜索