React_API

React-API


React.Component

React.Component 是使用 ES6 classes 方式定义 React 组件的基类:

class Greeting extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

React.PureComponent纯组件

React.PureComponentReact.Component 很相似。两者的区别在于 React.Component 并未实现 shouldComponentUpdate(),而 React.PureComponent 中以浅层对比 prop 和 state 的方式来实现了该函数。

如果赋予 React 组件相同的 props 和 state,render() 函数会渲染相同的内容,那么在某些情况下使用 React.PureComponent 可提高性能。

注意

React.PureComponent 中的 shouldComponentUpdate() 仅作对象的浅层比较。如果对象中包含复杂的数据结构,则有可能因为无法检查深层的差别,产生错误的比对结果。仅在你的 props 和 state 较为简单时,才使用 React.PureComponent,或者在深层数据结构发生变化时调用 forceUpdate() 来确保组件被正确地更新。你也可以考虑使用 immutable 对象加速嵌套数据的比较。

此外,React.PureComponent 中的 shouldComponentUpdate() 将跳过所有子组件树的 prop 更新。因此,请确保所有子组件也都是“纯”的组件。


React.PureComponent的深浅比较

浅比较只会比较 props 的第一层,如果传入的 props 是数组或对象,那么你需要格外小心。因为即使数组更新了,纯组件会在浅比较时认为新旧 props 是相同引用,因此不触发渲染。

可以使用JSON.parse和JSON.stringify对对象或者是数组进行深拷贝

父组件


import React, { Component } from 'react';
import Son from './Son'

class Father extends Component {
    constructor(props){
        super(props)
        this.state={array:[1,2,3,4,5]}
    }
    onClick=()=>{
        this.state.array.push(this.state.array.length+1)
        this.setState({
            array:this.state.array
        })
    }
    render() {
        return (<div>
            <button onClick={this.onClick}>btn</button>
            <Son array={this.state.array}
                name='Bruce Lee'>
            </Son>
        </div>);
    }
}

export default Father;

子组件

import React, { PureComponent, Component } from 'react';
import PropTypes from 'prop-types';

class Son extends PureComponent {
    static propTypes = {
        array: PropTypes.array,
        name: PropTypes.string
    }

    NumberList (array) {
        // key 必须有,否则产生警告。key 一般用id,提高渲染效率。万不得已使用 index
        const listItem = array.map((number) => <li key={number.toString()}>{number}</li>)
      
        return (
          <ul>{listItem}</ul>
        )
      }

    render() { 
        console.log('son ',this.props.array)
        return (<div>
                {this.props.name}
                <div>
                    {this.NumberList(this.props.array)} 
                </div>
            </div>  );
    }
}
 
export default Son;

父组件的click

 onClick=()=>{
        let newArray = JSON.parse(JSON.stringify(this.state.array));
        newArray.push(this.state.array.length+1)
        this.setState({
            array:newArray
        })
    }

另外,当父组件传入子组件的 props 有函数时,你可能也会遇到一些问题,比如:

父组件为:

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import MyButton from './MyButton'

class Father extends PureComponent {
    constructor(props) {
        super(props);
        this.state = { value:123 }
    }
    onClick=()=>{
        this.setState({
            value:this.state.value+1
        })
    }
    render() { 
        return (
            <div>
            <p>{this.state.value}</p>
            <MyButton
            callback={()=>this.onClick()}/>
            </div>);
    }
}

export default Father;

子组件为:

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';

class MyButton extends PureComponent {
    static propTypes={
        callback:PropTypes.func
    }
    constructor(props) {
        super(props);
        this.state = {  }
    }
    render() { 
        console.log('son')
        return (<button onClick={this.props.callback}>btn</button>);
    }
}

export default MyButton;

注意,这个时候,父组件传入子组件的 props callback 的写法是:

callback={()=>this.onClick()}

这种写法导致,每次传入子组件的 callback 都是一个新的函数对象,因此,每次父组件 render 时,子组件都会重新 render,效果为:

因此,我们修改为下面这种写法,即,每次传入子组件的 callback 都对应同一个对象,因此,子组件不重新进行渲染。我们修改父组件:

callback={this.onClick}这样传入的是函数

callback={()=>this.onClick()}表示的是把this.onClick()返回的结果作为匿名箭头函数的返回值,即每传入一次调用一次新的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容