资讯专栏INFORMATION COLUMN

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

izhuhaodev / 943人阅读

摘要:手挽手带你学入门二档组件开发的开始,合理运用生命周期和组件,能够让你的开发变地流利又这篇文章带你学会创建组件,运用组建。

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

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 (
            
        )
    }
   componentDidUpdate(){
        console.log("5.执行componentDidUpdate")       
   }
   componentWillUnmount(){
    //    这个在卸载的时候会调用 业务逻辑写里面就好了 
   }
}

生命周期简单介绍就这些了,真正工作中要根据业务需求来调用,大大增加你的开发效率,处理你开发中遇到的难题。

组件创建

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

那么 我们如何创建一个子组件呢?

export default class App extends Component {
    constructor(){
        super()
        this.state={
        
        }
    }
  
    render() {
        //要想使用子组件也很简单 用标签的形式拿进来就好了
        return (
            
        )
    }
  
}

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

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

我是子组件

) } }
组件传参

我们学会了如何创建组件,那么组件怎么传参呢?这个是非常重要的东西,毕竟组件之间不能通讯,那就没有创建它的意义了。

父子传参

在React中父子传参极其类似Vue 直接在标签上填写属性,但是在子组件接收的时候会有所不同

我们接着使用上面的代码

export default class App extends Component {
    constructor(){
        super()
        this.state={
        
        }
    }
  
    render() {
        //要想使用子组件也很简单 用标签的形式拿进来就好了
        return (
            
        )
    }
  
}

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

class Children extends Component{
    constructor(){
        super()
        this.state={
        
        }
    }
    // 通过这种形式 我们就可以把父组件的东西传递给子组件了,所有的属性存储在props里面,上面我们介绍生命周期的时候,也提了一下如何创建默认props。这里我们写一下

    render(){
        return(
            

我是子组件

{this.props.params}

) } // 如果父组件没有传递 params 我们又想使用默认的props 那么就要使用下面的写法 } Children.defaultProps = { params: "我是默认的东西" }; // 设置了默认props以后 如果我们不传参就会默认展示我们默认规定好的属性了

插槽(类似Vue solt)
为什么要把插槽放在这里讲解呢?实际上React的插槽是通过传参的形式下来的,怎么理解呢?我觉得放进代码中是最容易理解的。

export default class App extends Component {
    constructor(){
        super()
        this.state={
        
        }
    }
  
    render() {
        //要想使用子组件也很简单 用标签的形式拿进来就好了
        return (
            
                
传递第一个
传递第二个
传递第三个
) } } //下面我们再写一个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(

我是子组件

{/* 这里我用循环的方式把三个children取出来直接渲染即可 */} {this.props.children.map((item,key)=>{ return item })} {/* 我们更加直观一点 */} {this.props.children[1]} {this.props.children[0]} {this.props.children[2]} {/* 看到这里大家应该可以知道插槽的简单用法了吧 */}
) } // 如果父组件没有传递 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 (
            
{this.state.myPatams} {/* 这里我们把函数传递下去,一定要bind this 否则在我们在子组件中使用bind来调用的时候,this的指向会跑到子组件中 我们拿到的参数意义就不大了 当然箭头函数也是完全没问题的 */}
) } } //下面我们再写一个class 并且继承 Component 这就是一个组件了 class Children extends Component{ constructor(){ super() this.state={ } } render(){ return(

我是子组件

{/* 我们在这里调用父组件传递过来的方法,并且传入参数 */}
) } } 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 (
            
{this.state.myPatams} {/* 这里我们把函数传递下去,一定要bind this 否则在我们在子组件中使用bind来调用的时候,this的指向会跑到子组件中 我们拿到的参数意义就不大了 当然箭头函数也是完全没问题的 */}
) } } //下面我们再写一个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(

{this.state.emit}

{/* 我们在这里调用父组件传递过来的方法,并且传入参数 */}
) } } class ChildrenTwo extends Component{ constructor(){ super() this.state={ } } gaveParams(param){ emitter.emit("childrenEmit",param) //从第二个子组件触发并且传递参数 } render(){ return(

我是子组件

) } }
组件抽离

写了这么多,相信大家差不多会写自己的组件并且在组件中传递参数了,这里还有一个问题,大家是不是发现我的所有组件都写在了一个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 (
            
{this.state.myPatams} {/* 这里我们把函数传递下去,一定要bind this 否则在我们在子组件中使用bind来调用的时候,this的指向会跑到子组件中 我们拿到的参数意义就不大了 当然箭头函数也是完全没问题的 */}
) } }
// children.js
import React,{Component} from "react"

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

export class Children extends Component{  //我们这里使用的是export来暴露  如果只有一个组件 也可以使用 export default 来暴露
    constructor(){
        super()
        this.state={
        
        }
    }
    render(){

        return(
            

我是子组件

{/* 我们在这里调用父组件传递过来的方法,并且传入参数 */}
) } } Children.defaultProps = { params: "我是默认的东西" };

大功告成了 代码是不是清晰多了??

总结

这一期内容不多 主要是介绍组件的生命周期 使用方法 以及如何传参,这些内容可全都是干货,工作中会经常经常使用到,希望大家能自己写小demo来熟悉一下写法,下一期将会带大家学习React-Router 以及context和高阶组件的创建,为我们学习Redux打下基础

视频制作中

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101645.html

相关文章

  • 手挽手带你学VUE:二档 组件开发以及常用全局api

    摘要:我们想要在中做到子传参给父,那我们的父组件就要像子组件伸出小偷之手。所在组件的更新时调用,但是可能发生在其子更新之前。指令所在组件的及其子全部更新后调用。 视频教程 由于思否不支持视频链接 视频请移步 http://www.henrongyi.top 你能学到什么 二档视频当然要比一档视频难一点,如果前面的内容还没有消化完毕的话,还是建议大家继续消化前面的内容,然后再看接下来的部分。...

    fredshare 评论0 收藏0
  • 手挽手带你学VUE:二档 组件开发以及常用全局api

    摘要:我们想要在中做到子传参给父,那我们的父组件就要像子组件伸出小偷之手。所在组件的更新时调用,但是可能发生在其子更新之前。指令所在组件的及其子全部更新后调用。 视频教程 由于思否不支持视频链接 视频请移步 http://www.henrongyi.top 你能学到什么 二档视频当然要比一档视频难一点,如果前面的内容还没有消化完毕的话,还是建议大家继续消化前面的内容,然后再看接下来的部分。...

    Pink 评论0 收藏0
  • 手挽手带你学React:一档 React环境搭建,语法规则,基础使用

    摘要:当属性是一个回调函数时,函数接收底层元素或类实例取决于元素的类型作为参数。 手挽手带你学React入门第一期,带你熟悉React的语法规则,消除对JSX的恐惧感,由于现在开发中都是使用ES6语法开发React,所以这次也使用ES6的模式进行教学,如果大家对ES6不熟悉的话,先去看看class相关内容吧,这里我也慢慢带大家一步一步学会React。 视频教程 视频教程可移步我的个人博客:h...

    BicycleWarrior 评论0 收藏0
  • 手挽手带你学React:三档 React-router4.x的使用

    摘要:我们在内部来渲染不同的组件我们这里采用哈希路由的方式,鉴于的渲染机制,我们需要把值绑定进入内部。 手挽手带你学React入门三档,带你学会使用Reacr-router4.x,开始创建属于你的React项目 什么是React-router React Router 是一个基于 React 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 URL 间的同步。通俗一...

    SunZhaopeng 评论0 收藏0
  • 手挽手带你学React:四档(上)一步一步学会react-redux (自己写个Redux)

    手挽手带你学React入门四档,用人话教你react-redux,理解redux架构,以及运用在react中。学完这一章,你就可以开始自己的react项目了。 之前在思否看到过某个大神的redux搭建 忘记了大神的名字 这里只记得内容了 凭借记忆和当时的学习路线写下本文 隔空感谢 本人学习react-redux的时候遇到了很多坎,特别是不理解为什么这么用,这是什么东西,用来做什么。加上各种名词让人...

    sixgo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<