Na parte de hoje da tradução do tutorial do React, concluiremos o trabalho no aplicativo Todo e falaremos sobre como usar dados de componentes internos e os recursos JavaScript padrão para carregar dados de fontes externas.

→
Parte 1: visão geral do curso, razões para a popularidade do React, ReactDOM e JSX→
Parte 2: componentes funcionais→
Parte 3: arquivos de componentes, estrutura do projeto→
Parte 4: componentes pai e filho→
Parte 5: início do trabalho em um aplicativo TODO, noções básicas de estilo→
Parte 6: sobre alguns recursos do curso, JSX e JavaScript→
Parte 7: estilos embutidos→
Parte 8: trabalho contínuo na aplicação TODO, familiaridade com as propriedades dos componentes→
Parte 9: propriedades do componente→
Parte 10: Workshop sobre como trabalhar com propriedades e estilo de componentes→
Parte 11: geração dinâmica de marcação e método de matrizes de mapas→
Parte 12: workshop, terceira etapa do trabalho em uma aplicação TODO→
Parte 13: componentes baseados em classe→
Parte 14: workshop sobre componentes baseados em classe, status dos componentes→
Parte 15: oficinas de saúde componentes→
Parte 16: a quarta etapa do trabalho em um aplicativo TODO, manipulação de eventos→
Parte 17: quinta etapa do trabalho em um aplicativo TODO, modificando o estado dos componentes→
Parte 18: a sexta etapa do trabalho em um aplicativo TODO→
Parte 19: métodos do ciclo de vida dos componentesParte 20: a primeira lição sobre renderização condicional→
Parte 21: segunda lição e workshop sobre renderização condicional→
Parte 22: sétima etapa do trabalho em um aplicativo TODO, baixando dados de fontes externas→
Parte 23: primeira lição sobre como trabalhar com formulários→
Parte 24: Segunda lição sobre formulários→
Parte 25: Workshop sobre como trabalhar com formulários→
Parte 26: arquitetura do aplicativo, padrão Container / Component→
Parte 27: projeto do cursoLição 39. Oficina. Aplicação TODO. Estágio número 7
→
Original▍Job
Agora, o aplicativo Todo se parece com a figura a seguir.
Página do aplicativo no navegadorO
TodoItem
componente
TodoItem
fica assim:
import React from "react" function TodoItem(props) { return ( <div className="todo-item"> <input type="checkbox" checked={props.item.completed} onChange={() => props.handleChange(props.item.id)} /> <p>{props.item.text}</p> </div> ) } export default TodoItem
Sua tarefa é estilizar os itens da lista de acordo com o estado deles. A aparência dos casos concluídos deve ser diferente de incompleta. Ao formatar itens da lista que representam tarefas concluídas, seu texto pode ficar acinzentado, pode ser riscado, em itálico ou outras modificações podem ser feitas.
▍Solução
O problema apresentado aqui pode ser resolvido de várias maneiras. Usaremos o estilo
TodoItem
, que descreveremos como a constante
completedStyle
no código do componente funcional
TodoItem
. Aqui, configuramos as propriedades de texto
fontStyle
,
color
e
textDecoration
. Depois disso, usando a técnica de renderização condicional, atribuiremos esse estilo ao elemento
<p>
caso a empresa deduzida por ele seja marcada como concluída. Determinaremos isso com base na propriedade transmitida para a instância do componente, que está disponível como
props.item.completed
.
O código do componente convertido terá a seguinte aparência:
import React from "react" function TodoItem(props) { const completedStyle = { fontStyle: "italic", color: "#cdcdcd", textDecoration: "line-through" } return ( <div className="todo-item"> <input type="checkbox" checked={props.item.completed} onChange={() => props.handleChange(props.item.id)} /> <p style={props.item.completed ? completedStyle: null}>{props.item.text}</p> </div> ) } export default TodoItem
Veja como a aparência da página do aplicativo muda.
Página de aplicativo alterada no navegadorAo mesmo tempo, os estilos são aplicados ao definir e desmarcar os sinalizadores que indicam o status dos itens na lista de tarefas.
Isso conclui o trabalho no aplicativo Todo.
Lição 40. Fazendo Download de Dados de Fontes Externas
→
OriginalEm uma lição sobre métodos de ciclo de vida de componentes, falamos sobre o método
componentDidMount()
. Tente se lembrar de como isso funciona. Este método permite que você interfira na operação do componente executando algum código imediatamente após o componente ter sido adicionado à árvore DOM. Quando falamos sobre métodos de ciclo de vida de componentes, mencionei que o método
componentDidMount()
é mais frequentemente usado para carregar dados de algumas fontes externas. Esses dados são usados pelo componente para realizar sua finalidade.
Vamos começar as experiências de hoje com um novo projeto criado usando as
App.js
-app
App.js
cujo arquivo
App.js
contém o seguinte código:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = {} } render() { return ( <div> Code goes here </div> ) } } export default App
No código do componente
App
baseado em componente, descrevemos o método
componentDidMount()
e verificamos a operacionalidade da construção resultante, produzindo algo para o console desse método.
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = {} } componentDidMount() { console.log("Hi!") } render() { return ( <div> Code goes here </div> ) } } export default App
Saída para a string do console
Hi!
prova a funcionalidade do código, para que possamos continuar trabalhando. Como já mencionado, esse método geralmente carrega os dados necessários para o componente funcionar.
Nesta lição, usaremos várias ferramentas auxiliares que nos serão úteis ao carregar dados no componente.
O primeiro é o recurso JavaScript embutido. Estamos falando da
API Fetch , que é uma interface conveniente para obter recursos, com base em
promessas , que permitem executar solicitações HTTP, através das quais os dados são carregados.
A segunda ferramenta que usaremos é a
API de Guerra nas Estrelas . Este projeto é bom porque pode ser usado em aplicativos front-end sem dificuldades especiais (em particular, estamos falando sobre os recursos de configuração do CORS).
No método
componentDidMount()
, vamos usar a função
fetch()
, transmitindo o endereço para carregar dados, convertendo esses dados para o tipo que precisamos e, para verificar o funcionamento correto do sistema, envie esses dados para o console. Transformamos o código do método no seguinte formato:
componentDidMount() { fetch("https://swapi.co/api/people/1") .then(response => response.json()) .then(data => console.log(data)) }
Aqui, baixamos dados sobre um certo herói do filme, referente à API, depois convertemos o que veio do servidor para o formato JSON e depois imprimimos esses dados no console. O que entrou no console é mostrado na figura a seguir.
Os dados baixados da API Star Wars são enviados para o consoleComo você pode ver, um objeto com dados sobre Luke Skywalker entrou no console. Agora, depois de termos os dados, precisamos pensar em como exibi-los na página do aplicativo. Para resolver esse problema, primeiro leve em consideração o fato de que os dados baixados de fora, se não forem salvos em nenhum lugar, não poderão ser exibidos na página do aplicativo em um navegador. O local que serve para armazenar esses dados é o estado do componente. Adicione uma nova propriedade,
character
, representada por um objeto vazio ao estado do componente:
this.state = { character: {} }
Vamos armazenar nesta propriedade um objeto com uma descrição do personagem, dados sobre os quais é baixado de uma fonte externa. Eles existem como um objeto; portanto, quando inicializamos os estados, tornamos a propriedade do
character
um objeto vazio.
Depois disso, naquele local do código do método
componentDidMount()
, onde obtemos os dados, os escreveremos no estado usando o método
setState()
. Além disso, nesse caso, o que antes era armazenado no estado que não nos interessa, portanto, podemos simplesmente passar para esse método um objeto contendo uma nova representação do estado. Como resultado, chegamos a este código de método
componentDidMount()
:
componentDidMount() { fetch("https://swapi.co/api/people/1") .then(response => response.json()) .then(data => { this.setState({ character: data }) }) }
Para verificar a operação correta dos mecanismos que agora existem no código, exibiremos no método
render()
algo que deve estar presente no estado após a gravação dos dados carregados. Agora, o código do arquivo
App.js
ficará assim:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { character: {} } } componentDidMount() { fetch("https://swapi.co/api/people/1") .then(response => response.json()) .then(data => { this.setState({ character: data }) }) } render() { return ( <div> {this.state.character.name} </div> ) } } export default App
E aqui está como a página do aplicativo ficará no navegador.
Página do aplicativo no navegadorA
Luke Skywalker
texto de
Luke Skywalker
em uma página demonstra como os mecanismos de carregamento de dados funcionam.
Nosso aplicativo usa uma solicitação simples, em resposta à qual o aplicativo recebe uma pequena quantidade de dados que são rapidamente processados e exibidos na página. Leva muito pouco tempo para concluir todas essas ações. Portanto, os dados são exibidos na tela tão rapidamente que temos a impressão de que o componente, imediatamente após exibi-lo na tela, já o contém. Porém, se a fonte de dados remota for acessada usando uma linha de comunicação muito lenta ou a API da qual os dados são carregados responderem lentamente às solicitações, poderá demorar muito tempo até que o aplicativo possa exibir esses dados na tela . Todo esse tempo, a tela permaneceria em branco. Se isso ocorrer em aplicativos do mundo real, confunde seus usuários, que podem decidir que esses aplicativos não funcionam corretamente. Para antecipar uma situação semelhante, é necessário, durante o carregamento e o processamento dos dados, mostrar ao usuário uma mensagem correspondente. Isso não se aplica ao nosso tópico hoje, mas é aqui que será apropriado discuti-lo.
Em aplicativos reais, para alertar o usuário de que ele precisa aguardar uma determinada ação, como baixar dados, eles usam algo como um indicador de carregamento. No nosso caso, até que os dados sejam carregados e prontos para serem exibidos na página, mostraremos apenas o
loading...
do texto
loading...
Ao fazer isso, poderemos avaliar as possibilidades que o armazenamento de dados no estado do aplicativo nos oferece.
Adicione uma nova propriedade ao estado, indicando se os dados estão sendo carregados em algum momento. Chame-o de
loading
e inicialize-o como
false
. Depois disso, imediatamente antes de carregar dados usando
fetch()
, escrevemos
true
para esta propriedade.
Em seguida, no método
render()
, com base na propriedade state de
loading
, configuraremos o texto exibido na página. Aqui está a
App.js
código
App.js
após essas conversões.
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { loading: false, character: {} } } componentDidMount() { this.setState({loading: true}) fetch("https://swapi.co/api/people/1") .then(response => response.json()) .then(data => { this.setState({ character: data }) }) } render() { const text = this.state.loading ? "loading..." : this.state.character.name return ( <div> <p>{text}</p> </div> ) } } export default App
Este código, no entanto, não funciona corretamente. Ou seja, é assim que a página do aplicativo se parece agora.
Página do aplicativo no navegadorSupõe-se que a inscrição
loading...
deve ser exibida nela apenas ao baixar dados de uma fonte externa, mas parece que agora ela é exibida na página constantemente. Antes de continuar lendo, tente encontrar e corrigir erros no código.
Na verdade, o problema aqui é que, antes de iniciar o carregamento dos dados, configuramos o
loading
como
true
e, após a conclusão do download, não
loading
false
no
loading
. Como resultado, o
loading...
do texto
loading...
é sempre exibido na página. Não é difícil corrigir esse erro. Chega, no mesmo local em que escrevemos os dados carregados no estado, defina o
loading
como
false
. Como resultado, o código
App.js
o seguinte formato:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { loading: false, character: {} } } componentDidMount() { this.setState({loading: true}) fetch("https://swapi.co/api/people/1") .then(response => response.json()) .then(data => { this.setState({ loading: false, character: data }) }) } render() { const text = this.state.loading ? "loading..." : this.state.character.name return ( <div> <p>{text}</p> </div> ) } } export default App
Agora, ao carregar dados, a inscrição
loading...
aparece brevemente e, depois disso, o nome do personagem é exibido na página.
Sumário
Nesta lição, você concluiu o trabalho em um aplicativo Todo e aprendeu a usar o método do ciclo de vida do
componentDidMount()
e a API Fetch padrão para carregar dados de fontes externas, processá-los e exibi-los nas páginas. Além disso, discutimos aqui a implementação de um mecanismo para notificar o usuário sobre o aplicativo que está executando operações, o que pode levar muito tempo. Da próxima vez, falaremos sobre formulários.
Caros leitores! Como você carrega dados de fontes externas nos aplicativos React?