Tornou-se popular para os aplicativos terem uma configuração que permite alternar entre os modos escuro e claro. 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. Como alternativa, você pode criar um componente de botão de modo escuro que usa os ganchos useEffect e useState em vez de contexto. Ele alternará um atributo de dados no elemento do corpo que os estilos CSS podem direcionar.

O que você precisará

Para acompanhar este tutorial, você precisará do seguinte:

  • Uma versão recente do Node instalada em sua máquina.
  • Um entendimento básico de React e Ganchos de reação.
  • Um projeto inicial do React. Apenas criar um aplicativo React e você está pronto para ir.

Criar um componente de botão

O componente botão será responsável por alternar o tema de escuro para claro. Em um aplicativo real, esse botão pode fazer parte do componente Navbar.

instagram viewer

Na pasta src, crie um novo arquivo chamado Button.js e adicione o código a seguir.

importar { useEstado } a partir de 'reagir'

exportarpredefiniçãofunçãoBotão() {
const [theme, settheme] = useState("Sombrio")

const handleToggle = () => {
const novoTema = tema "leve"? "Sombrio": "leve"
settheme (novoTema)
}
Retorna (
<>
<botão className="themeBtn" onClick={handleToggle}>
{tema "leve"? <período>Sombrio</span>: <período>leve</span>}
</button>
</>
)
}

Primeiro, importe o hook useState() do React. Você o usará para acompanhar o tema atual.

No componente Button, inicialize o estado como escuro. A função handleToggle() cuidará da funcionalidade de alternância. Ele é executado cada vez que o botão é clicado.

Este componente também alterna o texto do botão quando altera o tema.

Para exibir o componente Button, importe-o para App.js.

importar Botão a partir de './Botão';
funçãoAplicativo() {
Retorna (
<div>
<Botão/>
</div>
);
}

exportarpredefinição Aplicativo;

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á criar os estilos CSS para o modo escuro e claro.

Em App.css, adicione o seguinte.

corpo {
--color-texto-primário: #131616;
--color-texto-secundário: #ff6b00;
--color-bg-primary: #E6EDEE;
--color-bg-secundário: #7d86881c;
fundo: var(--color-bg-primário);
cor: var(--color-texto-primário);
transição: fundo 0.25sfacilidade de entrada;
}
body[data-theme="leve"] {
--color-texto-primário: #131616;
--color-bg-primary: #E6EDEE;
}
body[data-theme="Sombrio"] {
--color-texto-primário: #F2F5F7;
--color-bg-primary: #0E141B;
}

Aqui, você está definindo os estilos do elemento body usando atributos de dados. Há o atributo de dados do tema claro 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 acordo com os dados. Se um usuário selecionar um tema escuro, você poderá definir o atributo de dados do corpo como escuro e a interface do usuário será alterada.

Você também pode modificar os estilos de elemento de botão para alterar com o tema.

.themeBtn {
preenchimento: 10px;
cor: var(--color-texto-primário);
fundo: transparente;
fronteira: 1px sólido var(--color-texto-primário);
cursor: ponteiro;
}

Modificar o componente do botão para alternar estilos

Para alternar os estilos definidos no arquivo CSS, você precisará definir os dados no elemento body na função handleToggle().

Em Button.js, modifique handleToggle() assim:

const handleToggle = () => {
const novoTema = tema "leve"? "Sombrio": "leve"
settheme (novoTema)
documento.body.dataset.theme = tema
}

Se você clicar no botão, o plano de fundo deve alternar de escuro para claro ou claro para escuro. No entanto, se você atualizar a página, o tema será redefinido. Para manter a configuração do tema, armazene a preferência do tema em armazenamento local.

Preferência do usuário persistente no armazenamento local

Você deve recuperar a preferência do usuário assim que o componente Button for renderizado. O gancho useEffect() é perfeito para isso, pois é executado após cada renderização.

Antes de recuperar o tema do armazenamento local, você precisa armazená-lo primeiro.

Crie uma nova função chamada storeUserPreference() em Button.js.

const storeUserSetPreference = (pref) => {
localStorage.setItem("tema", pref);
};

Esta função recebe a preferência do usuário como argumento e a armazena como um item chamado tema.

Você chamará essa função toda vez que o usuário alternar o tema. Então, modifique a função handleToggle() para ficar assim:

const handleToggle = () => {
const novoTema = tema "leve"? "Sombrio": "leve"
settheme (novoTema)
storeUserSetPreference (novoTema)
documento.body.dataset.theme = tema
}

A função a seguir recupera o tema do armazenamento local:

const getUserSetPreference = () => {
return localStorage.getItem("tema");
};

Você o usará no gancho useEffect para que cada vez que o componente renderize, ele busque a preferência do armazenamento local para atualizar o tema.

useEfeito(() => {
const userSetPreference = getUserSetPreference();

if (userSetPreference) {
settheme (userSetPreference)
}
documento.body.dataset.theme = tema
}, [tema])

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 do sistema operacional ou do navegador. A configuração pode ser clara ou escura. Em seu aplicativo, você precisaria verificar essa configuração imediatamente após 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 = "(prefere esquema de cores: escuro)";
const mql = janela.matchMedia (mediaQuery);
const temPreferência = tipo de mql.matches "boolean";

if (temPreferência) {
retornar mql.matches? "Sombrio": "leve";
}
};

Em seguida, modifique o gancho useEffect() para recuperar a preferência de consulta de mídia e use-a se nenhum tema estiver definido no armazenamento local.

useEfeito(() => {
const userSetPreference = getUserSetPreference();
const mediaQueryPreference = getMediaQueryPreference();

if (userSetPreference) {
settheme (userSetPreference)
} senão {
settheme (mediaQueryPreference)
}

documento.body.dataset.theme = tema
}, [tema])

Se você reiniciar seu aplicativo, o tema deve corresponder às configurações do seu sistema.

Usando o React Context para alternar o modo escuro

Você pode usar atributos de dados, CSS e ganchos React para alternar o tema de um aplicativo React.

Outra abordagem para lidar com o modo escuro no React é usar a API de contexto. O contexto do React permite que você compartilhe dados entre os componentes sem precisar passá-los pelos adereços. Ao usá-lo para alternar temas, você cria um contexto de tema que pode ser acessado em todo o aplicativo. Você pode então usar o valor do tema para aplicar estilos correspondentes.

Embora essa abordagem funcione, usar atributos de dados CSS é mais simples.