Tornou-se popular para os aplicativos terem uma laia que permite intervalar entre os modos escuro e simples. Talvez seja devido à popularidade das UIs escuras, talvez seja porque os aplicativos estão gradualmente se tornando mais configuráveis.
O contexto React é uma maneira fácil de compartilhar dados globalmente, mas pode dificultar a reutilização de componentes. Uma vez que selecção, você pode produzir um componente de botão de modo escuro que usa os ganchos useEffect e useState em vez de context. Ele alternará um atributo de dados no elemento do corpo que os estilos CSS podem direcionar.
O que você precisará
Para escoltar leste tutorial, você precisará do seguinte:
- Uma versão recente do Node instalada em sua máquina.
- Uma compreensão básica dos ganchos React e React.
- Um projeto inicial do React. Basta produzir um aplicativo React e você está pronto para iniciar.
Fabricar um componente de botão
O componente botão será responsável por intervalar o tema de escuro para simples. Em um aplicativo real, esse botão pode fazer troço do componente Navbar.
Na pasta src, crie um novo registo chamado Button.js e adicione o código a seguir.
import { useState } from 'react'export default function Button() {
const [theme, settheme] = useState("dark")
const handleToggle = () => {
const newTheme = theme === "light" ? "dark" : "light"
settheme(newTheme)
}
return (
<>
<button className="themeBtn" onClick={handleToggle}>
{theme=== "light" ? <span>dark</span> : <span>light</span>}
</button>
</>
)
}
Primeiro, importe o hook useState() do React. Você o usará para escoltar o tema atual.
No componente Button, inicialize o estado uma vez que escuro. A função handleToggle() cuidará da funcionalidade de alternância. Ele é executado cada vez que o botão é clicado.
Levante componente também alterna o texto do botão quando altera o tema.
Para exibir o componente Button, importe-o para App.js.
import Button from './Button';
function App() {
return (
<div>
<Button/>
</div>
);
}export default App;
Crie os estilos CSS
No momento, clicar no botão não altera a interface do usuário do aplicativo React. Para isso, primeiro você precisará produzir os estilos CSS para o modo escuro e simples.
Em App.css, adicione o seguinte.
body {
--color-text-primary:
--color-text-secondary:
--color-bg-primary:
--color-bg-secondary:
background: var(--color-bg-primary);
color: var(--color-text-primary);
transition: background 0.25s ease-in-out;
}
body[data-theme="light"] {
--color-text-primary:
--color-bg-primary:
}
body[data-theme="dark"] {
--color-text-primary:
--color-bg-primary:
}
Cá, você está definindo os estilos do elemento body usando atributos de dados. Há o atributo de dados do tema simples e o atributo de dados do tema escuro. Cada um deles possui variáveis CSS com cores diferentes. O uso de atributos de dados CSS permitirá que você alterne os estilos de concordância com os dados. Se um usuário selecionar um tema escuro, você poderá definir o atributo de dados do corpo uma vez que escuro e a interface do usuário será alterada.
Você também pode modificar os estilos de elemento de botão para mudar com o tema.
.themeBtn {
padding: 10px;
color: var(--color-text-primary);
background: transparent;
border: 1px solid var(--color-text-primary);
cursor: pointer;
}
Modificar o componente do botão para intervalar estilos
Para intervalar os estilos definidos no registo CSS, você precisará definir os dados no elemento body na função handleToggle().
Em Button.js, modifique handleToggle() assim:
const handleToggle = () => {
const newTheme = theme ==="light" ? "dark" : "light"
settheme(newTheme)
document.body.dataset.theme = theme
}
Se você clicar no botão, o projecto de fundo deve intervalar de escuro para simples ou simples para escuro. No entanto, se você atualizar a página, o tema será redefinido. Para manter a laia do tema, armazene a preferência do tema no armazenamento sítio.
Preferência do usuário persistente no armazenamento sítio
Você deve restabelecer a preferência do usuário mal o componente Button for renderizado. O gancho useEffect() é perfeito para isso, pois é executado posteriormente cada renderização.
Antes de restabelecer o tema do armazenamento sítio, você precisa armazená-lo primeiro.
Crie uma novidade função chamada storeUserPreference() em Button.js.
const storeUserSetPreference = (pref) => {
localStorage.setItem("theme", pref);
};
Esta função recebe a preferência do usuário uma vez que argumento e a armazena uma vez que um item chamado tema.
Você chamará essa função toda vez que o usuário intervalar o tema. Logo, modifique a função handleToggle() para permanecer assim:
const handleToggle = () => {
const newTheme = theme === "light" ? "dark" : "light"
settheme(newTheme)
storeUserSetPreference(newTheme)
document.body.dataset.theme = theme
}
A função a seguir recupera o tema do armazenamento sítio:
const getUserSetPreference = () => {
return localStorage.getItem("theme");
};
Você o usará no gancho useEffect para que cada vez que o componente renderize, ele busque a preferência do armazenamento sítio para atualizar o tema.
useEffect(() => {
const userSetPreference = getUserSetPreference();if (userSetPreference) {
settheme(userSetPreference)
}
document.body.dataset.theme = theme
}, [theme])
Obtendo a preferência do usuário nas configurações do navegador
Para uma experiência de usuário ainda melhor, você pode usar o prefere-esquema de cores Recurso de mídia CSS para definir o tema. Isso deve refletir as configurações do sistema de um usuário que ele pode controlar por meio de seu sistema operacional ou navegador. A laia pode ser clara ou escura. Em seu aplicativo, você precisaria verificar essa laia imediatamente posteriormente o carregamento do componente do botão. Isso significa implementar essa funcionalidade no gancho useEffect().
Primeiro, crie uma função que recupere a preferência do usuário.
Em Button.js, adicione o seguinte.
const getMediaQueryPreference = () => {
const mediaQuery = "(prefers-color-scheme: dark)";
const mql = window.matchMedia(mediaQuery);
const hasPreference = typeof mql.matches === "boolean";if (hasPreference) {
return mql.matches ? "dark" : "light";
}
};
Em seguida, modifique o gancho useEffect() para restabelecer a preferência de consulta de mídia e use-a se nenhum tema estiver definido no armazenamento sítio.
useEffect(() => {
const userSetPreference = getUserSetPreference();
const mediaQueryPreference = getMediaQueryPreference();if (userSetPreference) {
settheme(userSetPreference)
} else {
settheme(mediaQueryPreference)
}
document.body.dataset.theme = theme
}, [theme])
Se você reiniciar seu aplicativo, o tema deve corresponder às configurações do seu sistema.
Usando o React Context para intervalar o modo escuro
Você pode usar atributos de dados, CSS e ganchos React para intervalar o tema de um aplicativo React.
Outra abordagem para mourejar com o modo escuro no React é usar a API de contexto. O contexto do React permite que você compartilhe dados entre componentes sem precisar passá-los pelos props. Ao usá-lo para intervalar temas, você cria um contexto de tema que pode ser acessado em todo o aplicativo. Você pode logo usar o valor do tema para empregar estilos correspondentes.
Embora essa abordagem funcione, usar atributos de dados CSS é mais simples.