Primeiros Passos com React

Fala pessoal, tudo certo? Hoje, vou falar um pouquinho de React, a library para Front-end feita pelo Facebook e que tem ganhado muita popularidade nos últimos tempos. Bem, todo mundo já deve ter ouvido falar sobre, e nesse post eu vou falar um pouco sobre como o React funciona e como você pode dar os primeiros passos com ela para criar uma aplicação web.

Ao final do post, você pode encontrar o código final em um repositório no Github.

Link for this post in English / link para o post em português

O que é o React

O Facebook, criador do React, define o mesmo como uma library Javascript para construção de interfaces de usuário, apresentando como principais características ser declarativa, baseada em componentes e seguindo o conceito de “Aprenda uma vez, escreva em qualquer lugar”. O React também utiliza JSX, uma linguagem com sintaxe semelhante à do HTML, mas com algumas particularidades que facilitam e muito a criação de interfaces e componentes. Avaliemos rapidamente estas três características principais do React.

Declarativa

Um conceito usualmente aceito para programação declarativa é o de que neste tipo de programação, você define o que você quer, enquanto que no estilo ao qual é normalmente comparado, o estilo imperativo, você enumera cada passo, indicando como conseguir aquilo que você quer. Da forma como o React funciona, é assim que você define sua interface, e veremos como mais a frente.

Baseada em Componentes

Crie componentes isolados, cada um contendo seus próprios métodos, estado e propriedades (states e props), e combine-os para criar interfaces complexas de usuário.

Aprenda Uma Vez, Escreva em Qualquer Lugar

O React não assume nada com relação à tecnologia que você usa. Você pode usar o React com Django, com Angular, com Rails, combinar com NodeJS. Além disso, também é possível criar aplicativos para celular utilizando o React Native

Primeiros Passos

Chega de teoria e vamos aos primeiros passos. Começar a programar com React é muito fácil. Para começar, vamos criar uma estrutura básica: uma pasta “public”, com o arquivo “index.html” importando 3 libraries, que iremos precisar, que são o Babel, React e React DOM. Você pode referencia-los através do CDNJs, e seu arquivo inicial ficará da seguinte forma:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
    </head>

    <body>
        <div id="app"></div>        
    </body>
</html>

Este div, com o id “#app”, será o container para sua aplicação. É onde o React irá renderizar código em JSX, ou algum componente que criamos. Para renderizar nosso primeiro conteúdo com JSX, vamos usar a função “render”, do React DOM. Passaremos dois parâmetros para esta função. O primeiro é o código JSX que queremos renderizar, e o segundo é aonde esse código JSX será renderizado, que como já falamos, será o div com o id “app”. Para isso, vamos usar a função “getElementById”, do Javascript. Primeiramente, vamos renderizar um simples parágrafo:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
    </head>

    <body>
        <div id="app"></div>        

        <script type="text/babel">
            ReactDOM.render(
                <p>First React App</p>,
                document.getElementById('app')
            );
        </script>
    </body>    
</html>

Vamos usar o “http-server” (falei dele nesse post, clica aí e procura por “http-server”) para servir nossos arquivos. Rode o comando “http-server” e acesse http://localhost:8080/. Você verá o parágrafo na sua página. Parabéns, você criou sua primeira aplicação em React, funcionando.

Um pouquinho de JSX

O JSX tem mais algumas funcionalidades adicionais interessantes. A primeira delas é que você pode embutir código Javascript no layout do seu componente. Basta inserir o código Javascript entre chaves (“{}”). Vamos modificar nosso exemplo um pouquinho:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
    </head>

    <body>
        <div id="app"></div>        

        <script type="text/babel">
            var today = new Date();

            ReactDOM.render(
                <p>Hello, 2 + 2 = {2 + 2}  and today is day {today.getDate()} of the month {today.getMonth() + 1}</p>,
                document.getElementById('app')
            );
        </script>
    </body>    
</html>

Embutimos um pouco de Javascript no meio do layout, e o que você deve ver ao acessar o seu localhost é algo semelhante com a imagem abaixo:

Agora que já vimos como começar, vamos separar um pouco as coisas. Vamos tirar este script do final do nosso body e jogar em um arquivo separado. Este arquivo será o “app.jsx”, que ficará dentro da pasta “public”, na mesma pasta do seu arquivo “index.html”. Depois, vamos definir o atributo “src” do script que estava no “index.html” para “app.jsx”, para que ele possa fazer referência a este novo arquivo que criamos, com o código para renderizar o elemento “p” dentro do “div”. O arquivo “index.html” ficará assim:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
    </head>

    <body>
        <div id="app"></div>        

        <script type="text/babel" src="app.jsx"></script>
    </body>    
</html>

E o arquivo “app.jsx” ficará desta forma:

var today = new Date();

ReactDOM.render(
    <p>Hello, 2 + 2 = {2 + 2}  and today is day {today.getDate()} of the month {today.getMonth() + 1}</p>,
    document.getElementById('app')
);

Pronto. Agora temos nosso HTML e nosso código Javascript separados em arquivos diferentes. Vamos criar nosso primeiro componente:

Nosso Primeiro Componente React

Para criar componentes, você usualmente verá pelos guias, sites e tutoriais, duas formas possíveis. Existem também uma forma mais simples, mas mais limitada, que é basicamente a criação de uma função recebe como argumento um objeto “props” com dados que você deseja passar ao componente e retorna um elemento JSX. Basicamente, algo como o código abaixo (aproveitando o exemplo da documentação oficial), que pode ser feito em nosso arquivo “app.jsx”:

var props = {name: 'Felipe'};

function HelloComponent(props) {
    return <p>Hello, {props.name}</p>
}

ReactDOM.render(
    HelloComponent(props),
    document.getElementById('app')
);

“props” é uma abreviação de properties, ou propriedades, que nada mais são do que dados a serem utilizados pelo componente para sua lógica e renderização, e são passados para o componente.

Esta forma que vimos acima não é muito utilizada, mas ainda consta na documentação do React. Entre as formas mais utilizadas, existem duas. A primeira, mais antiga, utiliza o método “createClass()” do React. Dentro dele, definimos o método “render()”, que indica aquilo que deve ser exibido quando este componente é renderizado. Este método deve ser usado se você ainda não utiliza as funcionalidades do ES6. Mas como nós temos o Babel, nós temos estas funcionalidades, e iremos usar a nova forma, que é a recomendada atualmente na documentação oficial do React. E para quem usa o ES6, a forma indicada para criar um componente é extendendo a “class” do ES6 React.Component. Depois, passamos para o método “render” este componente, com a sintaxe similar à de um elemento HTML. Repare a necessidade da “/” no final. Caso você a esqueça, o código não irá funcionar. Vejamos em nosso exemplo:

class HelloComponent extends React.Component {
    render() {
        return (
            <p>This is HelloComponent</p>            
        );
    }
}

ReactDOM.render(
    <HelloComponent/>,
    document.getElementById('app')
)

Para passar “props” para o componente, basta inclui-las como atributos, especificando seu valor dentro de chaves, na hora de passar o componente ao “render”, e recupera-las dentro do componente através do “this.props” mais o nome da propriedade. Vejamos no exemplo para que fique mais claro:

class HelloComponent extends React.Component {
    render() {
        var name = this.props.name;

        return (
            <p>Hello, {name}. This is HelloComponent</p>            
        );
    }
}

ReactDOM.render(
    <HelloComponent name={"Felipe"} />,
    document.getElementById('app')
)

Agora que falamos de componentes e “props”, vamos falar um pouquinho de “state”.

Componentes e “state”

Enquanto as “props” são valores passados ao componente, o “state” é o estado atual do componente. Valores e dados que definem como um componente se comporta e é renderizado. Segundo a documentação oficial, o “state” é semelhante às “props”, dados usados pelo componente, mas é totalmente controlado pelo próprio.

Para definir o “state” inicial, precisamos criar um construtor no componente, e dentro deste construtor, damos um valor para this.state, que será um objeto com toda a definição do “state” inicial do componente. Vamos adicionar um contador, com o nome “counter”, ao “state” e adicionar um parágrafo no “render” do nosso componente com o valor do contador, que recuperamos através do “this.state.counter”:

class HelloComponent extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            counter: 0
        }
    }

    render() {
        var name = this.props.name;
        var counter = this.state.counter;

        return (
            <p>Hello, {name}. This is HelloComponent</p>
            <p>The current counter value is: {counter}</p>
        );
    }
}

ReactDOM.render(
    <HelloComponent name={"Felipe"} />,
    document.getElementById('app')
)

Opa, temos um erro. Se você atualizar seu navegador e for até o console de Javascript do navegador (no Chrome, aperte F12 e clique em Console), poderá ver a seguinte mensagem de erro: “Uncaught SyntaxError: http://localhost:8080/app.jsx: Adjacent JSX elements must be wrapped in an enclosing tag (16:12)”. Como o próprio erro diz, o JSX requer que no return de qualquer elemento, sempre haja um elemento “pai”, que englobe todos os outros elementos. Um problema facilmente solucionado ao incluir um “div” que englobe os 2 parágrafos:

class HelloComponent extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            counter: 0
        }
    }

    render() {
        var name = this.props.name;
        var counter = this.state.counter;

        return (
            <div>
                <p>Hello, {name}. This is HelloComponent</p>
                <p>The current counter value is: {counter}</p>
            </div>
        );
    }
}

ReactDOM.render(
    <HelloComponent name={"Felipe"} />,
    document.getElementById('app')
)

Se mudamos a definição do counter, na linha 6, de 0 para outro valor, 3, por exemplo, esta mudança se reflete em nossa página. Vamos agora criar um botão dentro do nosso componente. Este botão, ao ser clicado, irá chamar uma função que irá atualizar nosso “state”, aumentando em 1 o valor do counter. Esta mudança será refletida imediatamente na página. Vamos lá:

class HelloComponent extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            counter: 0
        }
    }

    render() {
        var name = this.props.name;
        var counter = this.state.counter;

        return (
            <div>
                <p>Hello, {name}. This is HelloComponent</p>
                <p>The current counter value is: {counter}</p>
                <button>Increment</button>
            </div>
        );
    }
}

ReactDOM.render(
    <HelloComponent name={"Felipe"} />,
    document.getElementById('app')
)

Pronto, já temos nosso botão. Agora vamos criar nossa função e vamos atrelar a mesma ao botão que criamos, com o evento “onClick”. Vamos criar o método “handleIncrement”, que será o responsável por incrementar a propriedade “counter” do “state”, definindo como o valor do “counter” no “state” o valor atual do mesmo (this.state.counter) + 1. E por fim, temos que fazer o “bind” da função dentro do constructor, para que o “this” esteja disponível quando a chamarmos e a mesma possa acessar, por exemplo o método “setState” do componente, responsável por atualizar o “state”. Vamos lá:

class HelloComponent extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            counter: 0
        }

        this.handleIncrement = this.handleIncrement.bind(this);
    }

    handleIncrement() {
        this.setState({
            counter: this.state.counter + 1
        })
    }

    render() {
        var name = this.props.name;
        var counter = this.state.counter;

        return (
            <div>
                <p>Hello, {name}. This is HelloComponent</p>
                <p>The current counter value is: {counter}</p>
                <button onClick={this.handleIncrement} >Increment</button>
            </div>
        );
    }
}

ReactDOM.render(
    <HelloComponent name={"Felipe"} />,
    document.getElementById('app')
)

Agora, acesse a sua página novamente, clique no botão e veja a mágica acontecer. O contador aumenta em 1 a cada clique no botão. E assim, temos nosso componente, com “props” e “state, além de um método que altera este valor contido no “state” do componente.

Resumo

Para resumir tudo o que fizemos neste post:

  • Criamos um arquivo HTML básico, referenciando o Babel, React e React DOM
  • Usamos o método “render” do React DOM para renderizar um parágrafo em nosso HTML com JSX, criando assim nossa primeira aplicação com React 🙂
  • Usamos mais um pouco de JSX para inserir código Javascript em nosso layout
  • Colocamos nossa estrutura HTML e nosso código Javascript em arquivos separados, facilitando a manutenção
  • Criamos nosso primeiro componente através da classe do Javascript ES6. Vimos o que são “props”, informação passada a um componente, e passamos uma “prop” para nosso componente
  • Aprendemos sobre “state”, que também são informações ou dados, mas totalmente gerenciados pelo componente em si, e não passados por outros componentes

Todo o código final encontrado neste post está neste repositório do Github: https://github.com/felipegalvao/react-first-steps

Abraços

One comment on “Primeiros Passos com React

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *