O que é Optional chaining:
O optional chaining é um operador de encadeamento de estrutura que nos auxilia a tratar os acessos a uma referência sem ocasionar erros. Os erros mais comuns ocasionados quando não utilizamos o optional chaining é “null” ou “undefined”. Basicamente ele válida expressivamente a estrutura/propriedades caso ela não exista. O operador do optinal chaining é utilizado da seguinte maneira “?.”
O que ele resolve?
Imagine que você esteja fazendo a leitura de uma estrutura json e em algum certo momento, um grupo/propriedade desta estrutura tenha a probabilidade de não existir. Certamente, quando seu código tentar acessar essa propriedade que não existe, irá ocorrer erro na sua aplicação. Com optional chaining, mesmo a propriedades não existindo, não ocorrerá quebra na sua aplicação.
Optional chaining no React:
Antes de aplicar o optional chaining no react de fato, vamos entender como o erro acontece. Para isto, vamos criar um projeto react simples:
create-react-app optinal-chaning
Após término da criação do projeto, abra o App.js e transforme este componente em um statefull:
Para simular os dados retornados de uma api, vamos criar uma constante que tem uma estrutura de um usuário e seus repositórios:
const user = {
login: 'wagnerww',
name: 'Wagner Ricardo Wagner',
details: {
email: 'wagnerricardonet@gmial.com',
},
repos: [
{
id: 1,
name: 'Prisma-Training',
stars: 1,
},
{
id: 2,
name: 'React-GarphQL',
},
],
};
Agora, vamos fazer a leitura destes valores no corpo do nosso componente e exibi-los em tela:
import React, { Component } from 'react';
const user = {
login: 'wagnerww',
name: 'Wagner Ricardo Wagner',
details: {
email: 'wagnerricardonet@gmial.com',
},
repos: [
{
id: 1,
name: 'Prisma-Training',
stars: 1,
},
{
id: 2,
name: 'React-GarphQL',
},
],
};
class App extends Component {
render() {
return (
<div>
<strong>Usuário</strong>
<p>{user.login}</p>
<p>{user.details.email}</p>
<strong>Repositórios:</strong>
{user.repos.map((repo, index) => (
<div>
<p>{repo.name}</p>
</div>
))}
<p />
<p />
</div>
);
}
}
Até aqui tudo bem, mas agora imagine que o grupo “details” ou “repos” não retornou de sua api. Retire o grupo “details” e veja o que acontece, quando é tentado acessar um valor desta estrutura:
Agora, vamos adicionar o optional chaining em nosso projeto para resolver este problema. Para isso vamos instalar 3 dependências :
yarn add @babel/plugin-proposal-optional-chaining customize-cra react-app-rewired
Configurando o optional chaining no projeto:
Acesse o arquivo package.json e altere os scripts de inicialização para utilizar o react-app-rewired:
Habilitando o uso do Babel no create-react-app:
É importante salientar que para utilizar o optional-chaining, é necessário configurar o Babel. Porém, como neste exemplo estou utilizando o create-react-app, este por sua vez este não permite que você faça alterações diretas no arquivo .babelrc. Para isso, precisamos criar um arquivo de configuração que irá habilitar o uso do Babel de uma forma personalizada. Caso, você está utilizando o método manual ou outro framework, isso pode variar um pouco ou até nem precise deste arquivo de configuração.
Para habilitar o Babel iremos criar um arquivo na pasta raíz do nosso projeto chamado “config-overrides.js”:
const { useBabelRc, override, useEslintRc } = require("customize-cra");
module.exports = override(useBabelRc(), useEslintRc());
Após habilitar a configuração personalizada do Babel, iremos criar o arquivo que terá as configurações dos plugins. Crie um novo arquivo chamado “.babelrc” na raíz do projeto. Nele, iremos habilitar o plugin do optional-chaining:
{
"plugins": [["@babel/plugin-proposal-optional-chaining", { "loose": false }]]
}
Resultado do optional-chaining na aplicação:
Agora, voltando ao nosso arquivo App.js, e implementando o acesso da propriedade email desta forma: “user.details?.email”, após iniciar nossa aplicação veremos que ela não irá quebrar e dar erro. Implemente também sobre os repositórios, o código deverá ficar assim:
import React, { Component } from 'react';
const user = {
login: 'wagnerww',
name: 'Wagner Ricardo Wagner',
details: {
email: 'wagnerricardonet@gmial.com',
},
repos: [
{
id: 1,
name: 'Prisma-Training',
stars: 1,
},
{
id: 2,
name: 'React-GarphQL',
},
],
};
class App extends Component {
render() {
return (
<div>
<strong>Usuário</strong>
<p>{user.login}</p>
<p>{user.details?.email}</p>
<strong>Repositórios:</strong>
{user.repos?.map((repo, index) => (
<div>
<p>{repo.name}</p>
</div>
))}
<p />
<p />
</div>
);
}
}
export default App;
Observações
Se você reparar, o seu arquivo ficou sinalizado em vermelho, como se estivesse com erro, porém isso é uma questão da style-guide do eslint. As dependências para configurações do style-guide já estão no repositório do projeto, porém não as descrevi neste artigo, por que não está definido uma solução para o optional-chaning no EsLint até o fechamento deste artigo. Existe uma issue em aberto que reporta este problema, você pode acompanha-la neste link:
Support Optional Chaining · Issue #511 · babel/babel-eslint
Conclusão
O plugin optional-chaining é uma forma menos verbosa para testar estruturas de dados e facilita o nosso desenvolvimento quando temos algum receio de que alguma propriedade/grupo possa não ser retornada da nossa api. Sendo assim, tê-lo instalado em nosso projeto é importante, ainda mais se o projeto tende a crescer.
O link do repositório do exemplo pode ser encontrado em meu GitHub:
Ficou com dúvidas?
Não deixe de entrar em contato com wagnerricardonet@gmail.com