Otimização do componente React, como evitar o desperdício de desempenho causado por renderização desnecessária

prefácio

No processo de desenvolvimento, definitivamente haverá componentes de relacionamento aninhados. Quando usamos Component, quando o estado ou as propriedades do componente pai são atualizados, independentemente de o estado e as propriedades do componente filho serem atualizados, a atualização do componente filho será acionado. , o que levará a muitas renderizações desnecessárias e desperdiçará muito desempenho. Hoje este artigo vai te ensinar como resolver esse problema

Problema se reproduz

Vejamos primeiro o exemplo de código a seguir:
Deve ser mais fácil de entender, três componentes são introduzidos na página e, em seguida, clicar no botão acionará a alteração de estado

import React, {
    
     Component } from 'react'

export class Root extends Component {
    
    
    state = {
    
    
        num: 0
    }
    add = () => {
    
    
        this.setState({
    
    num: this.state.num + 1})
    }
    render() {
    
    
        return (
            <div>Root Page
                <Header />
                <Main />
                <Footer />
                <p>{
    
    this.state.num}</p>
                <button onClick={
    
    this.add}>add</button>
            </div>
        )
    }
}

class Main extends Component {
    
    
    render() {
    
    
        console.log('Main组件渲染了')
        return <div>Main</div>
    }
}

class Header extends Component {
    
    
    render() {
    
    
        console.log('Header组件渲染了')
        return <div>Header</div>
    }
}

class Footer extends Component {
    
    
    render() {
    
    
        console.log('Footer组件渲染了')
        return <div>Footer</div>
    }
}

export default Root

Execute e veja o resultado:
insira a descrição da imagem aqui
parece que não há problema, na primeira vez que a página é atualizada, o componente é renderizado, mas clicamos no botão para dar uma olhada novamente:
insira a descrição da imagem aqui
você pode ver que quando o estado muda, nossos componentes são re-renderizado novamente, toda vez que os dados de atualização devem ser re-renderizados, então haverá muito renderização desnecessária, desperdiçando desempenho, vamos ver como resolvê-lo

problema resolvido

Opção 1. Use o julgamento do ciclo de vida do shouldComponentUpdate

Para o problema acima, podemos julgar se o método render precisa ser chamado de acordo com as props mais recentes e o estado mais recente, portanto, precisamos apenas controlar o subcomponente para julgar, não deixá-lo renderizar

Portanto, esse julgamento pode ser feito no ciclo de vida shouldComponentUpdate, que possui dois parâmetros, nextProps e nextState, para que possamos reescrevê-lo da seguinte forma:

class Main extends Component {
    
    
    shouldComponentUpdate(nextProps, nextState) {
    
    
        if (this.props.num !== nextProps.num) {
    
    
            return true
        }
        return false
    }
    render() {
    
    
        console.log('Main组件渲染了')
        return <div>Main</div>
    }
}

class Header extends Component {
    
    
    shouldComponentUpdate(nextProps, nextState) {
    
    
        if (this.props.num !== nextProps.num) {
    
    
            return true
        }
        return false
    }
    render() {
    
    
        console.log('Header组件渲染了')
        return <div>Header</div>
    }
}

Nesse caso, o componente de julgamento não será atualizado quando o botão for clicado, mas esse método não é muito recomendado, pois precisamos adicionar manualmente o julgamento condicional ao ciclo de vida de cada subcomponente, então vamos dar uma olhada em outro método.

Cenário 2. Usando PureComponent

Para introduzir PureComponent e usar PureComponent, basta alterar todos os Componentes para PureComponent

import React, {
    
     PureComponent } from 'react'

export class Root extends PureComponent {
    
    
    state = {
    
    
        num: 0
    }
    add = () => {
    
    
        this.setState({
    
    num: this.state.num + 1})
    }
    render() {
    
    
        return (
            <div>Root Page
                <Header />
                <Main />
                <Footer />
                <p>{
    
    this.state.num}</p>
                <button onClick={
    
    this.add}>add</button>
            </div>
        )
    }
}
class Main extends PureComponent {
    
    
    render() {
    
    
        console.log('Main组件渲染了')
        return <div>Main</div>
    }
}

class Header extends PureComponent {
    
    
    render() {
    
    
        console.log('Header组件渲染了')
        return <div>Header</div>
    }
}

class Footer extends PureComponent {
    
    
    render() {
    
    
        console.log('Footer组件渲染了')
        return <div>Footer</div>
    }
}

export default Root

Vamos examinar os resultados novamente e descobrir que quando o botão é clicado, o subcomponente não será atualizado repetidamente,
então geralmente usaremos PureComponent em vez de Component. Simplificando, PureComponent implementa shouldComponentUpdate. PureComponent executa comparação superficial por meio de props e state. Comparação superficial é uma função embutida no código-fonte do react. Ela substitui shouldComponentUpdate. Ela apenas compara a estrutura de dados externa. Contanto que a camada externa seja a mesmo, considera-se que não há alteração. , não irá comparar os dados em profundidade. Quando o PureComponent realmente funciona, é apenas em alguns componentes de exibição puros

Princípio PureComponent

Quando o componente for atualizado, se as props e o estado do componente não forem alterados, o método de renderização não será acionado, eliminando o processo de geração e comparação do virtualDOM, para que possa atingir o objetivo de melhorar o novo desempenho.

Alguns problemas com PureComponent

1. Não pode ser usado em componentes funcionais
2. Para comparação superficial, os dados profundos são inconsistentes, o que pode fazer com que a página não seja atualizada.
3. Não é adequado para uso em estado e props com vários níveis de objetos aninhados.

Acho que você gosta

Origin blog.csdn.net/weixin_45745641/article/details/123522432
Recomendado
Clasificación