O que estamos construindo
Neste projeto React para iniciantes, vamos aprender como usar ganchos de estado, manipular eventos, aplicar CSS com base no estado e muito mais! Confira:
Prefere tutoriais em vídeo?
Confira o tutorial do YouTube aqui.
Tente você mesmo
Se você quiser experimentar primeiro, aqui estão os cenários (você também pode pegar o código CSS / iniciador abaixo):
- Quando o usuário clica no “botão aumentar”, a temperatura deve aumentar
- A temperatura não pode ultrapassar 30
- Quando o usuário clica no “botão diminuir”, a temperatura deve diminuir
- A temperatura não pode ficar abaixo de 0
- Quando a temperatura é 15 ou superior, a cor do plano de fundo deve mudar para vermelho (DICA: incluí um estilo chamado “quente” que você pode usar)
- Quando a temperatura estiver abaixo de 15, a cor do plano de fundo deve ser azul (DICA: incluí um estilo chamado “frio” que você pode usar)
Código de instalação / arranque
NOTA: Suponho que você tenha uma configuração do ambiente de desenvolvimento React. Se não, confira este vídeo para ajudar você a começar.
Tudo o que precisamos para começar é usar create-react-app. Ligue um terminal e execute:
npx create-react-app temperature-control
Deixe o terminal fazer seu trabalho e abra o projeto no VS Code (ou o que você usar).
Em seguida, vá para index.js, exclua tudo e cole o seguinte:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Entrar index.css, exclua tudo e cole o seguinte:
body {
font-family: sans-serif;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
min-height: 100vh;
}
.app-container {
height: 400px;
width: 300px;
background: #2b5870;
border-radius: 20px;
box-shadow: 10px 10px 38px 0px rgba(0, 0, 0, 0.75);
}
.temperature-display-container {
display: flex;
justify-content: center;
align-items: center;
height: 70%;
}
.temperature-display {
display: flex;
border-radius: 50%;
color: #ffffff;
height: 220px;
width: 220px;
text-align: center;
justify-content: center;
align-items: center;
font-size: 48px;
border: 3px #ffffff solid;
transition: background 0.5s;
}
button {
border-radius: 100px;
height: 80px;
width: 80px;
font-size: 32px;
color: #ffffff;
background: rgb(105, 104, 104);
border: 2px #ffffff solid;
}
button:hover {
background: rgb(184, 184, 184);
cursor: pointer;
}
button:focus {
outline: 0;
}
.button-container {
display: flex;
justify-content: space-evenly;
align-items: center;
}
.neutral {
background: rgb(184, 184, 184);
}
.cold {
background: #035aa6;
}
.hot {
background: #ff5200;
}
Por fim, entre App.js, exclua tudo e cole o seguinte:
import React from 'react';
const App = () => {
return (
<div className="app-container">
<div className="temperature-display-container">
<div className="temperature-display">10°C</div>
</div>
<div className="button-container">
<button>+</button>
<button>-</button>
</div>
</div>
);
};
export default App;
Agora podemos abrir um terminal no VS Code e executar o seguinte:
npm start
Se tudo correu como planejado, você deve ver o seguinte:
Viva! Isso nos dá um bom modelo para brincar, sem ter que se preocupar com nenhum CSS.
Torne o valor da temperatura dinâmico – usando State
A primeira coisa que faremos é tornar o valor da temperatura dinâmico. Para fazer isso, vamos armazenar o valor da temperatura no estado. Isso facilita a obtenção do valor posteriormente e a execução da lógica usando-o.
Se algo mudar na sua interface do usuário, é uma boa ideia colocá-la em estado.
No App.js importar o useState prenda na parte superior do arquivo da seguinte maneira:
import React, { useState } from 'react';
Em seguida, adicione o seguinte dentro do Função de aplicativo:
const [temperatureValue, setTemperatureValue] = useState(10);
Uma rápida atualização sobre useState – permite manter dados no estado do componente. o useState hook nos dá duas coisas:
- uma variável que contém o valor do estado atual
- uma função para alterar o valor do estado.
Nesse caso, chamamos nossa variável de estado temperatureValue e chamou nossa função setTemperatureValue. Inicializamos nosso valor da temperatura para ter um valor de 10, passando o valor 10 ao gancho useState.
Agora que temos um valor de estado, é hora de usá-lo em nosso código. Lembre-se, as coisas que obtemos useState pode usar usado como qualquer variável e função JavaScript antiga (já que é isso que elas são).
Dentro do nosso JSX, queremos substituir o valor da temperatura codificado usando nossa nova variável de estado sofisticada. Mude esta linha:
<div className="temperature-display">10°C</div>
Para que se torne o seguinte:
<div className="temperature-display">{temperatureValue}°C</div>
Observe como usamos {} para renderizar nossa temperatureValue variável. Agora, quando nosso valor de temperatura for alterado, o componente será renderizado novamente e exibirá o novo valor de temperatura.
Nosso App.js arquivo até agora se parece com este:
import React, { useState } from 'react';
const App = () => {
const [temperatureValue, setTemperatureValue] = useState(10);
return (
<div className="app-container">
<div className="temperature-display-container">
<div className="temperature-display">{temperatureValue}°C</div>
</div>
<div className="button-container">
<button>+</button>
<button>-</button>
</div>
</div>
);
};
export default App;
Agora, se você executar o aplicativo e olhar para o navegador, verá que as coisas têm a mesma aparência de antes.
Mas se você mudar o valor inicial que passamos para o gancho useState de 10 para outra coisa (por exemplo, 15), você verá que o aplicativo é atualizado. Isso significa que nosso gancho de estado está funcionando!
Alterar estado ao clicar no botão
Vamos trabalhar para aumentar / diminuir o valor da temperatura quando os botões são clicados.
Como sabemos, o gancho useState nos fornece uma setTemperatureValue função que podemos usar para mudar o temperaturaValor. Então, faz sentido ligarmos isso ao botão onClick evento.
Vamos fazer o botão de aumento primeiro. Substitua o botão de aumento pelo seguinte:
<button onClick={() => setTemperatureValue(temperatureValue + 1)}>+</button>
Observe como isso chama o setTemperatureValue função. Tomamos a corrente temperatureValue, adicione 1 e passe isso como argumento.
Portanto, como o TemperatureValue começa em 10, adicionar 1 definirá o valor do estado como 11. Quando o botão for clicado novamente, o estado será definido como 12 e assim por diante.
Em seguida, faremos o mesmo com o botão diminuir. Substitua o botão de diminuição atual pelo seguinte:
<button onClick={() => setTemperatureValue(temperatureValue - 1)}>-</button>
Isso está fazendo a mesma coisa, exceto que estamos diminuindo a temperatureValue desta vez.
Nosso código agora se parece com isso:
import React, { useState } from 'react';
const App = () => {
const [temperatureValue, setTemperatureValue] = useState(10);
return (
<div className="app-container">
<div className="temperature-display-container">
<div className="temperature-display">{temperatureValue}°C</div>
</div>
<div className="button-container">
<button onClick={() => setTemperatureValue(temperatureValue + 1)}>+</button>
<button onClick={() => setTemperatureValue(temperatureValue - 1)}>-</button>
</div>
</div>
);
};
export default App;
Tente executar isso no navegador e clicar nos botões. Os valores vão aumentar / diminuir.
Alterando a cor com base no estado
Agora vamos fazer algumas coisas chiques. Queremos que a cor de fundo da tela mude, dependendo da temperatura (alta ou baixa).
Se a temperatura é de 15 graus ou mais, queremos mudar a cor de fundo para vermelho. Se tiver menos de 15 anos, queremos alterar a cor do plano de fundo para azul.
Se você der uma olhada no CSS, forneci 2 classes:
.coldque define o plano de fundo para azul.hotque define o fundo para vermelho
Se adicionarmos uma dessas classes ao display de temperatura div, muda de cor. Por exemplo:
<div className="temperature-display cold">{temperatureValue}°C</div>
dará à tela de temperatura um fundo azul, enquanto:
<div className="temperature-display hot">{temperatureValue}°C</div>
dará à tela de temperatura um fundo vermelho.
Ok, isso é legal e tudo, mas como é que dinamicamente adicionar essas classes com base no estado?
Lembre-se de que geralmente é uma boa ideia colocar no estado as coisas que podem mudar na sua interface do usuário. Portanto, state é um lugar perfeito para armazenar a classe CSS atual que queremos usar.
Vamos em frente e criar outro gancho de estado para segurar o temperaturaCor igual a:
const [temperatureColor, setTemperatureColor] = useState('cold');
Observe que inicializamos nossa temperaturaCor objeto de estado com um valor “frio” (como nosso valor de temperatura é inicialmente 10 graus, queremos que a cor do plano de fundo seja azul).
Podemos então usar literais de modelo para adicionar dinamicamente as classes que queremos usando essa variável de estado. Vá em frente e atualize o código com o seguinte:
<div className={`temperature-display ${temperatureColor}`}>{temperatureValue}°C</div>
Essa é uma sintaxe complicada de entender; portanto, não se preocupe se não entender imediatamente.
Tudo o que está fazendo é criar uma string e aplicar dinamicamente o temperaturaCor variável. Sempre que o temperaturaCor muda para “hot”, o componente será renderizado novamente e a classe CSS “hot” será adicionada à string className.
Nosso código até agora se parece com este:
import React, { useState } from 'react';
const App = () => {
const [temperatureValue, setTemperatureValue] = useState(10);
const [temperatureColor, setTemperatureColor] = useState('cold');
return (
<div className="app-container">
<div className="temperature-display-container">
<div className={`temperature-display ${temperatureColor}`}>{temperatureValue}°C</div>
</div>
<div className="button-container">
<button onClick={() => setTemperatureValue(temperatureValue + 1)}>+</button>
<button onClick={() => setTemperatureValue(temperatureValue - 1)}>-</button>
</div>
</div>
);
};
export default App;
Mude a inicial temperatureColor variável de estado para “quente” / “frio” e o fundo da tela de temperatura deve mudar.
Agora que sabemos que isso está funcionando, tudo o que precisamos fazer é alterar a variável de estado. Mas onde fazemos isso?
Bem, nós já temos um Manipulador onClick que altera o temperatureValue, faz sentido adicionar nossa nova lógica a esse manipulador.
Até agora, temos usado um função embutida para nossos manipuladores de eventos de clique. E usar funções embutidas é bom quando temos uma função de uma linha.
Mas quando temos uma função de várias linhas com um monte de lógica, é melhor mover a função para fora do JSX. Isso torna nosso código um pouco mais limpo.
Vá em frente e cole o seguinte logo abaixo de todas as coisas do estado:
const increaseTemperature = () => {
setTemperatureValue(temperatureValue + 1);
};
const decreaseTemperature = () => {
setTemperatureValue(temperatureValue - 1);
};
Aqui estamos definindo duas funções – uma que aumenta a temperatura e outra que diminui a temperatura.
Em seguida, queremos alterar os botões onClick propriedades para chamar essas funções em vez das funções embutidas que tínhamos anteriormente:
<button onClick={increaseTemperature}>+</button>
<button onClick={decreaseTemperature}>-</button>
Agora, em vez de usar uma função embutida, estamos passando uma referência para nosso raiseTemperature e decrementTemperature funções. Nosso código até agora se parece com este:
import React, { useState } from 'react';
const App = () => {
const [temperatureValue, setTemperatureValue] = useState(10);
const [temperatureColor, setTemperatureColor] = useState('cold');
const increaseTemperature = () => {
setTemperatureValue(temperatureValue + 1);
};
const decreaseTemperature = () => {
setTemperatureValue(temperatureValue - 1);
};
return (
<div className="app-container">
<div className="temperature-display-container">
<div className={`temperature-display ${temperatureColor}`}>{temperatureValue}°C</div>
</div>
<div className="button-container">
<button onClick={increaseTemperature}>+</button>
<button onClick={decreaseTemperature}>-</button>
</div>
</div>
);
};
export default App;
Observe como nada mudou ainda – estamos apenas refatorando nosso código e se preparando para as próximas mudanças.
Agora é muito mais fácil adicionar lógica de código para qualquer um dos eventos de clique no botão – apenas escrevemos nossa lógica na função apropriada e a vida é boa.
ESTÁ BEM! Com a refatoração de diversão fora do caminho, vamos voltar aos negócios. Então nós dissemos que Quando a temperatura é de 15 graus ou mais, queremos alterar o valor do estado temperatureColor.
Podemos adicionar essa lógica ao nosso raiseTemperature funcionar assim:
const increaseTemperature = () => {
const newTemperature = temperatureValue + 1;
setTemperatureValue(newTemperature);
if (newTemperature >= 15) {
setTemperatureColor('hot');
}
};
O que nos fizemos?
- Criamos uma variável para armazenar o newTemperature value (fizemos isso, pois usaremos essa variável em alguns lugares)
- Nós definimos o temperatureValue, como fizemos antes
- Nós escrevemos um declaração if para verificar se o newTemperature valor é maior ou igual a 15
- Se sim, então usamos o setTemperatureColor para definir como temperaturaCor valor do estado como “quente”
Portanto, sempre que clicamos no botão várias vezes, o temperatureValue for maior ou igual a 15, o valor temperaturaCor mudanças de variável, o componente é renderizado novamente e a classe “quente” é adicionada à exibição de temperatura como bruxaria.
Mas espere! Ainda não lidamos com a redução. O que é basicamente semelhante à função de aumento:
const decreaseTemperature = () => {
const newTemperature = temperatureValue - 1;
setTemperatureValue(newTemperature);
if (newTemperature < 15) {
setTemperatureColor('cold');
}
};
Desta vez, subtraímos um e verificamos se o novo valor está abaixo de 15 antes de alterar o temperatura cor
Nosso código final do aplicativo se parece com este:
import React, { useState } from 'react';
const App = () => {
const [temperatureValue, setTemperatureValue] = useState(10);
const [temperatureColor, setTemperatureColor] = useState('cold');
const increaseTemperature = () => {
const newTemperature = temperatureValue + 1;
setTemperatureValue(newTemperature);
if (newTemperature >= 15) {
setTemperatureColor('hot');
}
};
const decreaseTemperature = () => {
const newTemperature = temperatureValue - 1;
setTemperatureValue(newTemperature);
if (newTemperature < 15) {
setTemperatureColor('cold');
}
};
return (
<div className="app-container">
<div className="temperature-display-container">
<div className={`temperature-display ${temperatureColor}`}>{temperatureValue}°C</div>
</div>
<div className="button-container">
<button onClick={increaseTemperature}>+</button>
<button onClick={decreaseTemperature}>-</button>
</div>
</div>
);
};
export default App;
Execute o aplicativo e tudo deve funcionar – viva!
Um desafio para tentar
Você deve ter notado que nosso controle de temperatura não é muito seguro – o usuário pode aumentar a temperatura até atingir 100 ° C, fervendo até o esquecimento, ou diminuir a temperatura até atingir -100 ° C, transformando-se em um enorme gelo cubo.
O desafio, se você aceitar, é impedir que o valor da temperatura indo acima de 30 ° C, e impedi-lo de indo abaixo de 30 ° C.
DICA: O raiseTemperature e decrementTemperature funções são lugares perfeitos para adicionar essa lógica!