Verwenden der Kontext-API in React zum Erstellen eines globalen Anwendungsthemas

Hallo, dies ist mein erster Beitrag auf Habr. Ich hoffe du wirst interessiert sein.

Daher möchte ich eine Reihe von Posts starten, die direkt oder indirekt mit der Erstellung des UI-Kits zusammenhängen.

Bild

Das Ziel dieses Beitrags: Finden Sie eine Lösung, um das Thema einer Anwendung zu steuern, deren Komponenten in React.js implementiert React.js . Wir werden zwei globale Themen verwenden - dunkel und hell .

In diesem Beispiel werde ich das Modul create-react-context , um den Kontext zu erstellen.

Wir beginnen mit der Erstellung eines Ordners im Stammverzeichnis des Projekts ( src / ) mit dem Namen theme-context . Die Struktur dieses Ordners sieht folgendermaßen aus:

 theme-context/ ThemeConsumer/ ThemeConsumer.js index.js ThemeProvider/ ThemeProvider.js index.js constants.js context.js index.js 

Persönlich beginne ich immer mit der Datei index.js . Sie führen zu Beginn alle Importe und Exporte durch, und dann tut Ihr Kopf nicht weh.

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.js

Als nächstes erstellen wir einen Kontext mit createContext (Entschuldigung für das Wortspiel) und verwenden das Modul von hier aus .

 import createContext from 'create-react-context'; const { Provider, Consumer } = createContext(); export { Provider, Consumer }; 

Importieren Sie createContext , zerstören Sie es in Provider und Consumer und exportieren Sie sie.

theme-context / constants.js

Hier ist alles einfach, wir erstellen unsere Variablen, um die Hauptdateien nicht zu verschmutzen.

 export const themeLight = 'light'; export const themeDark = 'dark'; export const defaultTheme = themeLight; export const themes = [themeLight, themeDark]; 

Wie ich bereits sagte, wird unsere Anwendung zwei Themen haben - hell und dunkel.

theme-context / ThemeProvider / ThemeProvider.js

Hier werden wir über den Anbieter sprechen - die Komponente, die in jedem React.Context Objekt verfügbar ist. Es ermöglicht Verbrauchern, zuzuhören und auf sich ändernde Kontexte zu reagieren.

In unserem Beispiel ist die Requisite des ein theme , das auf alle dieses Provider . Provider

 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.js

In dieser Datei werden wir mit Consumer arbeiten - dies ist eine Komponente, die auf eine Änderung des Kontexts „lauscht, wartet“. Das untergeordnete Element dieser Komponente ist eine Funktion. Dies ist ein Muss bei der Verwendung von Consumer .

Diese Funktion empfängt die Werte des aktuellen Kontexts und gibt einen React Node zurück, React Node eine Komponente.

Aus der Dokumentation: Der Wert des Arguments (in unserem Fall {theme => / *, um etwas basierend auf dem Kontextwert * /} zu visualisieren) entspricht dem Requisitenthema theme nächsten übergeordneten Elements im Provider für diesen Kontext.

 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 }; 

Hier ist Folgendes zu beachten:
Wenn das Thema nicht explizit ausgewählt wurde, muss das Komponententhema automatisch ausgewählt werden. Dazu verwende ich das lodash von lodash - defaultTo . Diese Funktionalität kann jedoch auf viele andere Arten erreicht werden.

Das ist alles, der Themenkontext ist einsatzbereit!

Schauen wir uns an, wie man es anwendet. Lassen Sie uns eine einfache Komponente erstellen, die den Kontext unserer Anwendung abhört und darauf reagiert.

 .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); 

Also haben wir unsere <App /> in den Anbieter eingewickelt, und jetzt ist das Thema für alle Komponenten-Konsumenten in unserer Anwendung verfügbar. Als nächstes gibt <App /> <MyComponent /> , dies ist , und es erstellt unsere Komponente und <MyComponent /> ihr das Thema unserer Anwendung. Und schon ein Thema als Argument:

 <ThemeConsumer>{theme => renderMyComponent(theme)}</ThemeConsumer> 

Wir können es beim Erstellen einer Komponente verwenden
  const renderMyComponent = theme => { //      }; 

Den Arbeitscode finden Sie hier .

Das ist alles, ich hoffe, Sie finden diesen Beitrag nützlich. Im nächsten Beitrag werde ich versuchen, einen Medienkontext zu erstellen, dessen Funktionalität uns hilft, die Komponenten auf den Geräten des Geräts des Benutzers zu visualisieren.

Vielen Dank.

Source: https://habr.com/ru/post/de462963/


All Articles