• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

React教程一prophotoshop、state、refs、生命周期

武飞扬头像
迷糊的小小淘
帮助2

文章略长,耐心读完,受益匪浅哦~

学新通

 目录

前言

简介

JSX

面向组件编程

state

props

refs

组件生命周期


前言

简介

React框架由Facebook开发,和Vue框架一样,都是用于构建用户界面的JavaScript库;

它有如下三个特点:

  1. 采用组件化模式,声明式编程,提高开发效率及组件复用率
  2. 在React Native中可以使用React语法进行移动端开发
  3. 使用虚拟DOM和优秀的Diffing算法,尽量减少与真实DOM的交互;

如下是引入react的简单尝试:

  1.  
    // test.html
  2.  
    <body>
  3.  
    <!-- 引入react核心库 -->
  4.  
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
  5.  
    <!-- 引入react-dom库,用于支持react操作DOM -->
  6.  
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
  7.  
    <!-- 引入babel,用于将jsx解析为js -->
  8.  
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  9.  
    <div id="test"></div>
  10.  
    <!-- 记住这里的类型是text/babel,下面写的是jsx语法 -->
  11.  
    <script type="text/babel">
  12.  
    // 创建虚拟DOM
  13.  
    const VDOM = (
  14.  
    <div>
  15.  
    <h1>React初尝试</h1>
  16.  
    </div>
  17.  
    )
  18.  
    ReactDOM.render(VDOM, document.getElementById('test')) // 渲染虚拟DOM到页面
  19.  
    </script>
  20.  
    </body>

JSX

JSX(JavaScript XML)是react定义的一种类似于XML的js扩展语法,用于简化创建虚拟DOM的过程;下面列出一些简单语法:

  • 定义虚拟DOM时,不要写引号;
  • 标签中混入JS表达式时要用{ };
  • 样式的类名指定要用className;
  • 内联样式,要用style={{key: value;...;}}的方式,其中最外层{}表示是js表达式,内层{}表示个对象;
  • 样式的名称要用小驼峰命名,如fontSize
  • 只有一个根标签
  • 标签必须闭合
  • 标签首字母若为小写,则会将标签转为html中同名标签;若首字母为大写,则意味着是个组件

在使用中,利用babel将jsx编译成js使用;

补充,由于只有一个跟标签,所以可以使用<Fragment></Fragement>标签或者<></>进行包裹,它俩的区别是Fragment组件可接收标签属性key,其余标签不接受;<>啥标签属性也不接受~

面向组件编程

在react中,组件分为函数式组件和类式组件;

  • 函数式组件

函数式组件即为在创建虚拟DOM时使用函数定义;

  1.  
    // test.html
  2.  
    <body>
  3.  
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
  4.  
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
  5.  
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  6.  
    <div id="test"></div>
  7.  
    <script type="text/babel">
  8.  
    // 函数式组件,名为test组件
  9.  
    function Test() {
  10.  
    console.log(this) // undefined,babel编译后开启了严格模式
  11.  
    // 返回虚拟DOM
  12.  
    return (
  13.  
    <div>
  14.  
    <h1>React初尝试</h1>
  15.  
    </div>
  16.  
    )
  17.  
    }
  18.  
    ReactDOM.render(<Test/>, document.getElementById('test')) // 渲染test组件到页面
  19.  
     
  20.  
    </script>
  21.  
    </body>

 执行ReactDOM.render之后,发生了什么?

  1. React解析组件标签,找到Test组件
  2. 发现Test组件是用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后渲染到页面上

在无hook之前,函数式组件中只有props这一种属性;

  • 类式组件

类式组件即为在创建虚拟DOM时使用类定义;

  1.  
    // test.html
  2.  
    <body>
  3.  
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
  4.  
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
  5.  
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  6.  
    <div id="test"></div>
  7.  
    <script type="text/babel">
  8.  
    // 创建类式组件,皆要继承于React.Component
  9.  
    class Demo extends React.Component {
  10.  
    render() {
  11.  
    return (
  12.  
    <div>
  13.  
    <h1>React初尝试</h1>
  14.  
    </div>
  15.  
    )
  16.  
    }
  17.  
    }
  18.  
    ReactDOM.render(<Demo />, document.getElementById('test')) // 渲染虚拟DOM到页面
  19.  
    </script>
  20.  
    </body>

其中render函数是定义在Demo组件的原型对象对象上,供实例使用;

执行了ReactDom.render之后发生了什么?

  1. React解析组件标签,找到Demo组件;
  2. 发现组件是类式组件,随后React自动new出来该类的实例,并通过该实例调用原型上的render方法;
  3. 将render方法返回的虚拟DOM转为真实DOM,随后渲染到页面上

类式组件上有三大属性:state,props,refs,下面分别进行介绍;

state

state是由多个key-value组成的对象;通过更新组件的state来更新页面(重新渲染页面);

state中的数据不能被直接更改,要通过调用setState({key: value})方法来更改;

如下案例为通过改变state中的workDay属性渲染页面显示工作日/休息日:

  1.  
    <body>
  2.  
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
  3.  
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
  4.  
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  5.  
    <div id="test"></div>
  6.  
    <script type="text/babel">
  7.  
    class Demo extends React.Component {
  8.  
    // 构造函数传参为props,在react中创建类组件时,若写构造函数,则要写super,否则会引起内部bug
  9.  
    constructor(props) {
  10.  
    super(props)
  11.  
    this.state = {workDay: true} // 设置状态
  12.  
    // 未避免调用changeDay方法时this指向为undefined,因此利用bind将this指向变为实例对象,并将改变this指向后的函数赋值给实例对象的change属性
  13.  
    this.change = this.changeDay.bind(this)
  14.  
    }
  15.  
    render() {
  16.  
    return (
  17.  
    <div>
  18.  
    <h1 onClick={this.change}>今天是{this.state.workDay? '工作日': '休息日'}</h1>
  19.  
    </div>
  20.  
    )
  21.  
    }
  22.  
    // 该方法原本是给Demo类的实例对象使用的,若作为事件的回调函数,则this指向为undefined(babel为严格模式)
  23.  
    changeDay() {
  24.  
    this.setState({workDay: !this.state.workDay}) // 要利用setState方法修改state值
  25.  
    }
  26.  
    }
  27.  
    ReactDOM.render(<Demo />, document.getElementById('test')) // 渲染虚拟DOM到页面
  28.  
    </script>
  29.  
    </body>

 如注释所说,若利用类组件方法创建组件,若在类中写了构造函数,则接收props参数的同时要写上super(props),以防止报错~

在构造函数中可以创建state对象,用以控制页面显示~

在定义事件函数时,若写在类中作为普通函数(则该方法如changeDay,只有作为类的实例对象被调用时,this才有值,即为该实例对象),作为事件被调用时,此时this为undefined。为解决此问题,可以在构造函数中改变this指向并赋值给另一属性,则此时的this就是类的实例对象,则可以正常被使用~

学新通

可以看到Demo实例上有change方法,原型对象上有changeDay方法;

修改state属性时,不能采用直接赋值的形式,要调用原型对象中的方法setState实现;

当然,state方法还有简单写法(不通过构造函数的方式),因为在继承类中,可省略构造函数constructor,同时若在类中直接写赋值语句,也可以将该属性给每个实例对象使用~所以可以将state直接写在类中,将事件回调函数用属性赋值的方式进行定义;

  1.  
    <script>
  2.  
    class Person {
  3.  
    constructor(name, age) {
  4.  
    this.name = name
  5.  
    this.age = age
  6.  
    }
  7.  
    workerType = '程序媛'
  8.  
    say = function(){
  9.  
    console.log(`我的工作是${this.workerType}`)
  10.  
    }
  11.  
    }
  12.  
    let person = new Person('人类', 100)
  13.  
    console.log(person)
  14.  
    person.say()
  15.  
    </script>

学新通

因此用在此例中如下:

  1.  
    <script type="text/babel">
  2.  
    // 创建类式组件,皆要继承于React.Component
  3.  
    class Demo extends React.Component {
  4.  
    state = {workDay: true} // 设置状态
  5.  
    change = () => {
  6.  
    console.log(this); // 此处一定要写成箭头函数形式, this的指向才为实例对象
  7.  
    this.setState({workDay: !this.state.workDay})
  8.  
    }
  9.  
    render() {
  10.  
    return (
  11.  
    <div>
  12.  
    <h1 onClick={this.change}>今天是{this.state.workDay? '工作日': '休息日'}</h1>
  13.  
    </div>
  14.  
    )
  15.  
    }
  16.  
    }
  17.  
    ReactDOM.render(<Demo />, document.getElementById('test')) // 渲染虚拟DOM到页面
  18.  
    </script>

修改state不能采用直接赋值的方法,要使用setState方法,该方法有两种使用方式:

  1.  
    setState(stateChange, [callback]) // 方法一 对象式更新状态
  2.  
    // stateChange为状态改变的对象[该对象可以体现出状态的更改]
  3.  
    // callback是可选的回调函数,它在状态更新完毕、界面也更新后(render调用后)才被调用
  1.  
    setState(updater, [callback]) // 方法二 函数式更新状态
  2.  
    // updater为返回状态改变的对象[该对象可以体现出状态的更改]的函数,其参数可接收到state和prop
  3.  
    // callback是可选的回调函数,它在状态更新完毕、界面也更新后(render调用后)才被调用

 两种改变state状态的方式,都可以接收到一个回调函数,该回调函数是异步的,在该回调里才能拿到state的最新状态~

关于state的总结如下:

  • state可定义在构造函数中,也可利用赋值语句方法赋值;
  • state不可直接修改,需要调用原型对象中的setState方法(对象式方法与组件式方法);
  • 类组件中的render方法this指向组件实例对象(由react自动创建出来),组件初始化时会被渲染一次,随后在每次组件更新时被调用;
  • 类组件中的构造函数只会被调用一次;
  • 类组件中普通函数定义改变this指向有两种方法:

                ① 在构造函数中利用bind等方法改变this指向;

                ② 利用箭头函数 函数赋值的方式

props

        prop用于存放组件中的标签属性;props用于存放所有组件中的标签属性;

  1.  
    <script type="text/babel">
  2.  
    class Demo extends React.Component {
  3.  
    render() {
  4.  
    return (
  5.  
    <ul>
  6.  
    <li>{this.props.name}</li>
  7.  
    <li>{this.props.age}</li>
  8.  
    <li>{this.props.grade}</li>
  9.  
    </ul>
  10.  
    )
  11.  
    }
  12.  
    }
  13.  
    ReactDOM.render(<Demo name="小红" age="18" grade="100"/>, document.getElementById('test')) // 渲染虚拟DOM到页面
  14.  
    const properties = {name: '小明', age: '19', grade: "90"}
  15.  
    ReactDOM.render(<Demo {...properties}/>, document.getElementById('test1')) // 渲染虚拟DOM到页面
  16.  
    </script>

学新通

复用组件时,利用props可传入不同的标签属性用于展示~

可以限制属性的类型,默认值及是否必输特性,需引入prop-types库;通过给类组件的propTypes和defaultProps进行赋值;

注意:

自 React v15.5 起,React.PropTypes 已移入另一个包中。请使用 prop-types 库 代替。

  1.  
    <body>
  2.  
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
  3.  
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
  4.  
     
  5.  
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  6.  
    <!-- 引入prop-types库 -->
  7.  
    <script src="https://unpkg.com/prop-types@15.6/prop-types.js"></script>
  8.  
     
  9.  
    <div id="test"></div>
  10.  
    <div id="test1"></div>
  11.  
    <script type="text/babel">
  12.  
    class Demo extends React.Component {
  13.  
    render() {
  14.  
    const {name, age, grade} = this.props
  15.  
    return (
  16.  
    <ul>
  17.  
    <li>{name}</li>
  18.  
    <li>{age}</li>
  19.  
    <li>{grade}</li>
  20.  
    </ul>
  21.  
    )
  22.  
    }
  23.  
    }
  24.  
    Demo.propTypes = {
  25.  
    name: PropTypes.string.isRequired, // 设置name为字符串类型且为必输项
  26.  
    age: PropTypes.number, // 设置age为数字类型
  27.  
    grade: PropTypes.number // 设置grade为数字类型
  28.  
    }
  29.  
    Demo.defaultProps = {
  30.  
    age: 18, // 设置age默认值为18
  31.  
    grade: 90 // 设置grade默认值为90
  32.  
    }
  33.  
    ReactDOM.render(<Demo name="小红" grade={100}/>, document.getElementById('test')) // 渲染虚拟DOM到页面
  34.  
    const properties = {name: '小明', age: 19}
  35.  
    ReactDOM.render(<Demo {...properties}/>, document.getElementById('test1')) // 渲染虚拟DOM到页面
  36.  
    </script>
  37.  
    </body>

当然,也可以通过static关键字对其进行限制;

  1.  
    <script type="text/babel">
  2.  
    class Demo extends React.Component {
  3.  
    static propTypes = {
  4.  
    name: PropTypes.string.isRequired, // 设置name为字符串类型且为必输项
  5.  
    age: PropTypes.number, // 设置age为数字类型
  6.  
    grade: PropTypes.number // 设置grade为数字类型
  7.  
    }
  8.  
    static defaultProps = {
  9.  
    age: 18, // 设置age默认值为18
  10.  
    grade: 90 // 设置grade默认值为90
  11.  
    }
  12.  
    render() {
  13.  
    const {name, age, grade} = this.props
  14.  
    return (
  15.  
    <ul>
  16.  
    <li>{name}</li>
  17.  
    <li>{age}</li>
  18.  
    <li>{grade}</li>
  19.  
    </ul>
  20.  
    )
  21.  
    }
  22.  
    }
  23.  
    ReactDOM.render(<Demo name="小红" grade={100}/>, document.getElementById('test')) // 渲染虚拟DOM到页面
  24.  
    const properties = {name: '小明', age: 19}
  25.  
    ReactDOM.render(<Demo {...properties}/>, document.getElementById('test1')) // 渲染虚拟DOM到页面
  26.  
    </script>

函数式组件也可以使用props,通过给函数传参的方式拿到props:

  1.  
    <body>
  2.  
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
  3.  
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
  4.  
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  5.  
    <!-- 引入prop-types库 -->
  6.  
    <script src="https://unpkg.com/prop-types@15.6/prop-types.js"></script>
  7.  
     
  8.  
    <div id="test"></div>
  9.  
    <div id="test1"></div>
  10.  
    <script type="text/babel">
  11.  
    function Demo(props) {
  12.  
    const {name, age, grade} = props
  13.  
    return <ul>
  14.  
    <li>{name}</li>
  15.  
    <li>{age}</li>
  16.  
    <li>{grade}</li>
  17.  
    </ul>
  18.  
    }
  19.  
    Demo.propTypes = {
  20.  
    name: PropTypes.string.isRequired, // 设置name为字符串类型且为必输项
  21.  
    age: PropTypes.number, // 设置age为数字类型
  22.  
    grade: PropTypes.number // 设置grade为数字类型
  23.  
    }
  24.  
    Demo.defaultProps = {
  25.  
    age: 18, // 设置age默认值为18
  26.  
    grade: 90 // 设置grade默认值为90
  27.  
    }
  28.  
    ReactDOM.render(<Demo name="小红" grade={100}/>, document.getElementById('test')) // 渲染虚拟DOM到页面
  29.  
    const properties = {name: '小明', age: 19}
  30.  
    ReactDOM.render(<Demo {...properties}/>, document.getElementById('test1')) // 渲染虚拟DOM到页面
  31.  
    </script>
  32.  
    </body>

对props的总结如下:

  • 组件标签的所有属性都保存在props中
  • props属性是可读的,不能对其修改(会报错)
  • 可以利用propTypes以及defaultProps对属性类型、是否必输、默认值进行设置

refs

利用refs来表示某标签节点本身,避免操作dom获得标签;有三种形式:

  • 通过字符串赋值方式
<input ref="input">{name}</input>
  1.  
    <script type="text/babel">
  2.  
    class Demo extends React.Component {
  3.  
    state = {age: 17}
  4.  
    addAge = () => {
  5.  
    const newage = Number(this.refs.span.innerText) 1 // 利用this.refs.span可以拿到span节点
  6.  
    this.setState({age: newage})
  7.  
    }
  8.  
    render() {
  9.  
    return (
  10.  
    <div>
  11.  
    <span ref="span">{this.state.age}</span><br/>
  12.  
    <button onClick={this.addAge}>加一</button>
  13.  
    </div>
  14.  
    )
  15.  
    }
  16.  
    }
  17.  
    ReactDOM.render(<Demo name="小红" age={10}/>, document.getElementById('test')) // 渲染虚拟DOM到页面
  18.  
    </script>

该方法使用简单,但是要少用(有bug,以后可能会被弃用);

  • 回调函数方式的ref定义

可以在定义ref使用回调函数,传入的参数恰恰是该节点本身;将该参数赋值给其它变量获取即可;

<input ref={ (ele) => {this.input1 = ele} }>{name}</input>
  1.  
    <script type="text/babel">
  2.  
    class Demo extends React.Component {
  3.  
    state = {age: 17}
  4.  
    addAge = () => {
  5.  
    const newage = Number(this.span.innerText) 1 // 利用this.refs.span可以拿到span节点
  6.  
    this.setState({age: newage})
  7.  
    }
  8.  
    render() {
  9.  
    return (
  10.  
    <div>
  11.  
    <span ref={(ele) => {this.span = ele}}>{this.state.age}</span><br/>
  12.  
    <button onClick={this.addAge}>加一</button>
  13.  
    </div>
  14.  
    )
  15.  
    }
  16.  
    }
  17.  
    ReactDOM.render(<Demo name="小红" age={10}/>, document.getElementById('test')) // 渲染虚拟DOM到页面
  18.  
    </script>

利用回调函数方式定义ref时,在更新过程中会被执行两次:一次传入参数为null,第二次才是正常的节点元素,这是因为在每次更新时会创建一个新的函数实例,所以React清空旧的ref并设置新的,当然该差别在开发中没啥影响;见官网说明:Refs and the DOM – React

学新通

  • createRef创建ref容器

Refs是使用React.createRef()创建的,并通过ref属性附加到React元素。在构造组件时,通过将Refs分配给实例属性,以便可以在整个组件中引用它们;创建一个标记一个,React.createRef()与标签是一对一关系;使用时须通过.current拿到该节点元素;

  1.  
    <script type="text/babel">
  2.  
    class Demo extends React.Component {
  3.  
    state = {age: 17, age1: 19}
  4.  
    myRef = React.createRef() // 创建标记加的span节点
  5.  
    myRef1 = React.createRef() // 创建标记减的span节点
  6.  
    addAge = () => {
  7.  
    const newage = Number(this.myRef.current.innerText) 1 // 利用this.myRef.current可以拿到span节点
  8.  
    this.setState({age: newage})
  9.  
    }
  10.  
    subAge = () => {
  11.  
    const newage = Number(this.myRef1.current.innerText) - 1 // 利用this.myRef1.current可以拿到span节点
  12.  
    this.setState({age1: newage})
  13.  
    }
  14.  
    render() {
  15.  
    return (
  16.  
    <div>
  17.  
    <span ref={this.myRef}>{this.state.age}</span><br/>
  18.  
    <button onClick={this.addAge}>加一</button><br/>
  19.  
    <span ref={this.myRef1}>{this.state.age1}</span><br/>
  20.  
    <button onClick={this.subAge}>减一</button>
  21.  
    </div>
  22.  
    )
  23.  
    }
  24.  
    }
  25.  
    ReactDOM.render(<Demo />, document.getElementById('test')) // 渲染虚拟DOM到页面
  26.  
    </script>

对于refs的总结:

有三种方式使用refs

  • 字符串形式的ref
<input ref="input">{name}</input>
  • 回调形式的ref
<input ref={ (ele) => {this.input1 = ele} }>{name}</input>
  • 使用React.createRef()创建
  1.  
    myRef = React.createRef()
  2.  
    <input ref={ this.myRef }></input>

节点元素需通过this.myRef.current拿到;

在开发中,要尽量减少对ref的使用,可以通过event.target拿到发生事件的DOM元素;

组件生命周期

组件生命周期是指组件对象从创建到死亡会经历一些特定阶段。又称为组件生命钩子; 

学新通

  图片来源React lifecycle methods diagram

 上图展示了reactV16.4以后所有的生命周期函数,

  • 组件挂载时,依次会执行类的构造函数construtor、getDerivedStateFromProps、render函数及componentDidMount

组件挂载通过ReactDOM.render()触发;

static getDerivedStateFromProps(props, state)

 getDerivedStateFromProps会在调用render方法之前被调用,它应返回一个对象来更新state,若返回null则表示不更新任何内容(不写该函数表示返回null)。该函数适用于state的值在任何时候都取决于props。

componentDidMount()方法会在组件挂载后(插入到DOM树中)立即调用。一般在此阶段发送网络请求、开启定时器、订阅消息等;

  1.  
    <script type="text/babel">
  2.  
    class Demo extends React.Component {
  3.  
    state = {age: 17}
  4.  
    myRef = React.createRef() // 创建标记加的span节点
  5.  
    addAge = () => {
  6.  
    const newage = Number(this.myRef.current.innerText) 1 // 利用this.myRef.current可以拿到span节点
  7.  
    this.setState({age: newage})
  8.  
    }
  9.  
    render() {
  10.  
    return (
  11.  
    <div>
  12.  
    <span ref={this.myRef}>{this.state.age}</span><br/>
  13.  
    <button onClick={this.addAge}>加一</button><br/>
  14.  
    </div>
  15.  
    )
  16.  
    }
  17.  
    static getDerivedStateFromProps() {
  18.  
    console.log('getDerivedStateFromProps')
  19.  
    return {age: 21}
  20.  
    // 此处返回state对象中的age为21时,则不论点多少次按钮,age都不会被改变; 若返回null,则age会被修改
  21.  
    }
  22.  
    componentDidMount() {
  23.  
    console.log('componentDidMount') // 在此处设置定时器,发送请求,订阅消息等
  24.  
    }
  25.  
    }
  26.  
    ReactDOM.render(<Demo />, document.getElementById('test')) // 渲染虚拟DOM到页面
  27.  
    </script>
  • 组件更新时,依次执行getDerivedStateFromProps、shouldComponentUpdate、render、getSnapShotBeforeUpdate、componentDidUpdate

组件更新由组件内部setState或者父组件更新触发;

shouldComponentUpdate()返回布尔值,用以判断React组件的输出是否受当前state或props更改的影响,默认值是true,表示state每次发生变化组件都会重新渲染;该方法在首次渲染或使用forceUpdate()时不会被调用;但是官网建议慎用哦~

此方法仅作为性能优化的方式而存在。不要企图依靠此方法来“阻止”渲染,因为这可能会产生 bug。

学新通

getSnapshotBeforeUpdate(prevProps, prevState)

getSnapshotBeforeUpdate()方法在最近一次渲染输出(提交到DOM节点)之前调用。它使得组件能在发生更改之前从DOM中捕获一些信息,如滚动位置。此方法的任何返回值都将作为参数传递给componentDidUpdate();该方法并不常用;

componentDidUpdate(prevProps, prevState, snapshot)

componentDidUpdate()方法会在组件更新后立即调用。首次渲染不会执行该方法。如果组件实现了getSnapshotBeforeUpdate()方法,则它的返回值将作为第三个参数传递给componentDidUpdate(),否则该参数为undefined;

  1.  
    <script type="text/babel">
  2.  
    class Demo extends React.Component {
  3.  
    state = {age: 17}
  4.  
    myRef = React.createRef() // 创建标记加的span节点
  5.  
    addAge = () => {
  6.  
    const newage = Number(this.myRef.current.innerText) 1 // 利用this.myRef.current可以拿到span节点
  7.  
    this.setState({age: newage})
  8.  
    }
  9.  
    render() {
  10.  
    return (
  11.  
    <div>
  12.  
    <span ref={this.myRef}>{this.state.age}</span><br/>
  13.  
    <button onClick={this.addAge}>加一</button><br/>
  14.  
    </div>
  15.  
    )
  16.  
    }
  17.  
    static getDerivedStateFromProps(props, state) {
  18.  
    console.log('getDerivedStateFromProps')
  19.  
    return props
  20.  
    }
  21.  
    componentDidMount() {
  22.  
    console.log('componentDidMount')
  23.  
    }
  24.  
    shouldComponentUpdate() {
  25.  
    console.log('shouldComponentUpdate')
  26.  
    return true
  27.  
    // 此处设为false则点击按钮不会被更新,下面两个方法就不会被执行,点击true则正常更新
  28.  
    }
  29.  
    getSnapshotBeforeUpdate(prevProps, prevState) {
  30.  
    console.log('getSnapshotBeforeUpdate')
  31.  
    return 123
  32.  
    }
  33.  
    componentDidUpdate(prevProps, prevState, snapshot) {
  34.  
    console.log('componentDidUpdate')
  35.  
    return 456
  36.  
    }
  37.  
    }
  38.  
    ReactDOM.render(<Demo />, document.getElementById('test')) // 渲染虚拟DOM到页面
  39.  
    </script>
  • 组件卸载时,执行componentWillUnmount()

组件卸载通过ReactDOM.unmountComponentAtNode触发

componentWillUnmount()用在组件卸载及销毁之前直接调用,一般在此阶段执行必要的清理操作,如清除定时器、取消网络请求或清除在componentDidMount()中创建的订阅;

下图展示了常用的声明周期函数,在日常开发中经常被使用。

学新通

图片来源React lifecycle methods diagram

备注:旧版本中有几个弃用的声明周期函数,如 componentWillUnmount() 、componentWillUpdate() 、componentWillReceiveProps(),了解即可~


To be continue~

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbjgae
系列文章
更多 icon
同类精品
更多 icon
继续加载