Olá, este é o meu primeiro post no Habr. Espero que você esteja interessado.
Então, quero iniciar uma série de postagens direta ou indiretamente relacionadas à criação do ui-kit.

O objetivo desta publicação: Encontre uma solução para controlar o tema de um aplicativo cujos componentes são implementados no
React.js
. Usaremos dois temas globais -
escuro e
claro .
Neste exemplo, usarei o módulo
create-react-context
para criar o contexto.
Começamos criando uma pasta na raiz do projeto (
src / ) chamada
theme-context . A estrutura desta pasta ficará assim:
theme-context/ ThemeConsumer/ ThemeConsumer.js index.js ThemeProvider/ ThemeProvider.js index.js constants.js context.js index.js
Pessoalmente, eu sempre começo com o arquivo
index.js . Você faz todas as importações e exportações no início e, em seguida, sua cabeça não faz mal a elas.
theme-context / index.js export { ThemeProvider } from './ThemeProvider'; export { ThemeConsumer } from './ThemeConsumer';
theme-context / ThemeConsumer / index.js export { ThemeConsumer } from './ThemeConsumer';
theme-context / ThemeProvider / index.js export { ThemeProvider } from './ThemeProvider';
theme-context / context.jsEm seguida, criaremos um contexto usando
createContext
(desculpe o trocadilho), usando o módulo
daqui .
import createContext from 'create-react-context'; const { Provider, Consumer } = createContext(); export { Provider, Consumer };
Importe
createContext
,
createContext
-o em
Provider
and
Consumer
e exporte-os.
theme-context / constants.jsTudo é simples aqui, criamos nossas variáveis para não poluir os arquivos principais.
export const themeLight = 'light'; export const themeDark = 'dark'; export const defaultTheme = themeLight; export const themes = [themeLight, themeDark];
Como eu disse anteriormente, nosso aplicativo terá dois temas - claro e escuro.
theme-context / ThemeProvider / ThemeProvider.jsAqui falaremos sobre o provedor - o componente que está disponível em cada objeto
React.Context
. Permite que os consumidores escutem e respondam a contextos em mudança.
Em nosso exemplo, o suporte
é um
theme
que será transferido para todos os fluxos de
desse
Provider
a.
import React from 'react'; import { Provider } from '../context'; import { defaultTheme, themes } from '../constants'; function ThemeProvider({ theme, children }) { return <Provider value={theme}>{children}</Provider>; } export { ThemeProvider };
theme-context / ThemeConsumer / ThemeConsumer.jsNeste arquivo, trabalharemos com o Consumidor - este é um componente que "escuta, espera" por uma mudança de contexto. O filho deste componente é uma função. Esta é uma obrigação ao usar o
Consumer
.
Esta função recebe os valores do contexto atual e retorna um
React Node
, em outras palavras, um componente.
A partir da documentação: o valor do argumento (no nosso caso {theme => / * para visualizar algo com base no valor do contexto * /}) será igual ao
theme
props
theme
pai mais próximo na árvore do
Provider
para este contexto.
import React from 'react'; import { defaultTo } from 'lodash'; import { Consumer } from '../context'; import { defaultTheme, themes } from '../constants'; function ThemeConsumer(props) { return <Consumer>{theme => props.children(defaultTo(theme, props.defaultTheme))}</Consumer>; } export { ThemeConsumer };
Aqui vale a pena prestar atenção ao seguinte:
Se o tema não foi selecionado explicitamente, precisamos que o tema do componente seja selecionado automaticamente. Para isso, uso o
lodash
-
defaultTo
. No entanto, essa funcionalidade pode ser alcançada de várias outras maneiras.
Isso é tudo, o contexto do tema está pronto para uso!
Vamos ver como aplicá-lo. Vamos criar um componente simples que escute e responda ao contexto de nosso aplicativo.
.my-class { font-family: sans-serif; text-align: center; font-size: 30px; } .my-class-light { color: #39cccc; } .my-class-dark { color: #001a33; }
import React from "react"; import ReactDOM from "react-dom"; import cx from "classnames"; import { ThemeConsumer, ThemeProvider } from "./theme-context"; import "./styles.css"; function MyComponent() { const renderMyComponent = theme => { const myComponentClassName = cx("my-class", { "my-class-dark": theme === "dark", "my-class-light": theme === "light" }); return ( <div className={myComponentClassName}> <h1> </h1> </div> ); }; return <ThemeConsumer>{theme => renderMyComponent(theme)}</ThemeConsumer>; }; function App() { return ( <MyComponent /> ); } const rootElement = document.getElementById("root"); ReactDOM.render( // theme dark <ThemeProvider theme="light"> <App /> </ThemeProvider> , rootElement);
Então, envolvemos nosso
<App />
no provedor e agora o tema ficou disponível para todos os componentes-consumidores em nosso aplicativo. Em seguida,
<App />
retorna
<MyComponent />
, este é
, e ele criará nosso componente e passará o tema do nosso aplicativo. E já tendo um tópico como argumento:
<ThemeConsumer>{theme => renderMyComponent(theme)}</ThemeConsumer>
podemos usá-lo ao criar um componente
const renderMyComponent = theme => {
O código de trabalho pode ser encontrado aqui .
É isso, espero que você ache este post útil. Na próxima postagem, tentarei criar um
contexto de mídia , cuja funcionalidade nos ajudará a visualizar os componentes no equipamento do dispositivo do usuário.
Obrigada