✅ Notícias, temas e plug-ins da WEB e do WordPress. Aqui compartilhamos dicas e as melhores soluções para sites.

Convertendo React.createClass para React.Component

21

No meu último artigo falei sobre como corrigir versões mais antigas do React para funcionar em um ambiente moderno. Neste artigo vou mais longe e dou um guia passo a passo para atualizar um componente React clássico para um moderno, mudando a React.createClassmaneira de fazer as coisas para o método moderno e preferido React.Component.

Os arquivos que precisamos estarão nas pastas ‘Original’ e ‘Final’ do diretório de componentes na solução GitHub que acompanha.

Obter arquivos de tutorial do GitHub

Novamente trabalhando com o componente [react-checkbox-list](https://github.com/sonyan/react-checkbox-list) da Sony An (disponível como react-checkbox-listem npm ). Este guia mostra passo a passo como substituir a estrutura e os métodos de um React.createClasscomponente clássico por um moderno React.Component.

Começando com o .jsxarquivo na react-checkbox-listsolução, primeiro vamos excluir o .jsarquivo e renomeá-lo, .jspois os .jsxarquivos não precisam mais ser nomeados de forma diferente.

Isso nos dá o seguinte código inicial:


'use strict';
var React = require('react');

module.exports = React.createClass({
    displayName: 'CheckBoxList',

    propTypes: {
        defaultData: React.PropTypes.array,
        onChange: React.PropTypes.func
    },

    getInitialState: function() {
        return {
            data: this.props.defaultData || []
        };
    },

    handleItemChange: function(e) {
        var selectedValues = [],
            newData = [];

        this.state.data.forEach(function(item) {
            if(item.value === e.target.value) {
                item.checked = e.target.checked;
            }
            if(item.checked) {
                selectedValues.push(item.value);
            }
            newData.push(item);
        });

        this.setState({data: newData});

        if(this.props.onChange) {
            this.props.onChange(selectedValues);
        }
    },

    reset: function() {
        var newData = [];
        this.state.data.forEach(function(item) {
            item.checked = false;
            newData.push(item);
        });

        this.setState({data: newData});
    },

    checkAll: function() {
        var newData = [];
        this.state.data.forEach(function(item) {
            item.checked = true;
            newData.push(item);
        });

        this.setState({data: newData});
    },

    render: function() {
        var options;

        options = this.state.data.map(function(item, index) {
            return (<div key={'chk-' + index} className="checkbox">
                    <label>
                        <input
                            type="checkbox"
                            value={item.value}
                            onChange={this.handleItemChange}
                            checked={item.checked? true: false} /> {item.label}
                    </label>
                </div>
            );
        }.bind(this));

        return (<div>
                {options}
            </div>
        );
    }
});

Convertendo o componente

Ao tentar carregar este código, o primeiro erro que recebemos éUncaught Error: Module build failed: SyntaxError: The @jsx React.DOM pragma has been deprecated as of React 0.12

Erro não capturado: Falha na compilação do módulo: SyntaxError: O pragma @jsx React.DOM foi preterido a partir do React 0.12

É simples o suficiente para corrigir isso. Basta remover a linha /** @jsx React.DOM */da parte superior do documento.

Agora temos Uncaught TypeError: Cannot read property 'array' of undefinedo mesmo erro do tutorial de patch. Isso ocorre porque o React.propTypes foi preterido na versão 15.50 do React, então de acordo com esse tutorial, vá em frente e instale o pacote PropTypes com o comando via npm. Vamos importar isso para o nosso pacote mais tarde.[React.createClass](https://wholesomecode.ltd/blog/broken-react-createclass-component-lets-fix-it/)

npm install --save prop-types

O que se segue agora é uma revisão completa da base de código, então não podemos atualizar e corrigir um erro como fizemos anteriormente, então não saberemos se funcionou até o final. Preparar-se!

Vamos começar substituindo a React.createClassfunção declarando um novo React.Component. Altere nosso código para que fique assim:

'use strict';
import React from 'react';

class CheckBoxList extends React.Component {
...
}

Observe que fizemos algumas coisas aqui:

  • Removido o comentário JSX de abertura
  • Alterado o tipo de declaração var React =...para import React from 'react';este é a maneira moderna de fazer declarações no React.
  • Agora declaramos uma nova classe de CheckBoxList, em vez de exportar uma função.
  • Devido à sintaxe do objeto agora estar entre parênteses {...}, precisamos descartar o fechamento);

No entanto, esta nova classe agora está faltando uma maneira de exportá-la para que outros componentes possam usá-la, então vamos adicionar uma declaração de exportação na parte inferior desse código.

'use strict';
import React from 'react';

class CheckBoxList extends React.Component {
...
}

export default CheckBoxList;

Em nosso código original, a primeira linha de código na função era displayName: 'CheckBoxList',nossa exportação agora lida com isso, para que possamos remover esse código completamente.

A próxima linha declara propTypesque estes agora estão fora da classe e precisam da PropTypesdependência que adicionamos via npm. Vamos adicionar isso em nossas importações e escrever os PropTypes assim:

'use strict';
import React from 'react';
import PropTypes from 'prop-types';

class CheckBoxList extends React.Component {
...
}

CheckBoxList.propTypes = {
    defaultData: PropTypes.array,
    onChange: PropTypes.func,
};

export default CheckBoxList;

Em seguida, o estado é declarado através do método getInitialStatecom React.Componentque definimos nosso estado inicial com um construtor. Adicione o seguinte código em nossa compilação:

...
class CheckBoxList extends React.Component {
    constructor( props) {
        super( props );
        this.state = {
            data: [],
        }
    }
...
}
...

Lá vamos nós, que configura o estado do componente, mas espere, nós ainda não dissemos a ele de onde obter seu estado. É aí que componentWillMountvem a calhar.

...
class CheckBoxList extends React.Component {
    constructor( props) {
        super( props );
        this.state = {
            data: [],
        }
    }

    componentWillMount() {
        this.setState({
            data: this.props.defaultData,
        });
    }
...
}
...

Uma coisa importante a ser observada é que os métodos internos de React.Componentnão terminam em vírgulas (,), portanto, certifique-se de que quaisquer métodos adicionados ao componente não terminem em vírgula!

Em seguida, vamos adicionar a função de renderização de volta. Esta é provavelmente a parte mais fácil, é quase a mesma coisa, com a diferença chave que mudamos render: function() {para apenas render() {.

...
class CheckBoxList extends React.Component {
...
    render() {
        var options;

        options = this.state.data.map(function(item, index) {
            return (<div key={'chk-' + index} className="checkbox">
                    <label>
                        <input
                            type="checkbox"
                            value={item.value}
                            onChange={this.handleItemChange}
                            checked={item.checked? true: false} /> {item.label}
                    </label>
                </div>
            );
        }.bind(this));

        return (<div>
                {options}
            </div>
        );
    }
...
}
...

Para fins de manter este tutorial direto ao ponto, não converterei os dois métodos resete, checkAllno entanto, os conceitos usados ​​para a porta do método handleItemChangeapple para ambos, portanto, sinta-se à vontade para experimentá-los.

Para migrar o handleItemChangemétodo, primeiro precisamos remover a vírgula de fechamento (,) e alterar o tipo de declaração da função handleItemChange: function(e) {para handleItemChange( e) {garantir que ainda passemos ecomo parâmetro do evento.

Vamos adicionar isso acima do nosso método de renderização.

...
class CheckBoxList extends React.Component {
...
    handleItemChange( e) {
        var selectedValues = [],
            newData = [];

        this.state.data.forEach(function(item) {
            if(item.value == e.target.value) {
                item.checked = e.target.checked;
            }
            if(item.checked) {
                selectedValues.push(item.value);
            }
            newData.push(item);
        });

        this.setState( {data: newData} );

        if(this.props.onChange) {
            this.props.onChange(selectedValues);
        }
    }
...
}
...

Nosso componente agora será renderizado, porém não será funcional. Ao tentar clicar em uma caixa de seleção, você receberá o erro Uncaught TypeError: Cannot read property 'state' of undefined.

Erro de tipo não capturado: não é possível ler a propriedade ‘estado’ de indefinido

Isso porque em nosso handleItemChangemétodo, onde tentamos acessar o estado, thisé indefinido. Para corrigir isso, precisamos vincular nossa função thisadicionando a seguinte linha em nosso construtor: this.handleItemChange = this.handleItemChange.bind( this );.

...
class CheckBoxList extends React.Component {
    constructor( props) {
        super( props );
        this.state = {
            data: [],
        }
        this.handleItemChange = this.handleItemChange.bind( this );
    }
...
}
...

E aí está, nosso recém-convertido componente React em ação.

Convertendo React.createClass para React.ComponentReact.createClass para React.Component

Código-fonte do tutorial

Você pode baixar o código-fonte da versão original e final do componente no GitHub. O plugin contém um bloco WordPress Gutenberg que você pode usar para brincar com o código, com três arquivos que você pode excluir conforme aplicável:

Convertendo React.createClass para React.ComponentOs arquivos de tutorial do GitHub para a conversão de React.createClass para React.Component

Fonte de gravação: wholesomecode.ltd

Este site usa cookies para melhorar sua experiência. Presumiremos que você está ok com isso, mas você pode cancelar, se desejar. Aceitar Consulte Mais informação