Menggunakan API Konteks dalam Bereaksi untuk membuat tema aplikasi global

Hai, ini posting pertama saya di Habr. Saya harap Anda akan tertarik.

Jadi, saya ingin memulai serangkaian posting yang secara langsung atau tidak langsung terkait dengan pembuatan ui-kit.

gambar

Tujuan dari posting ini: Temukan solusi untuk mengontrol tema aplikasi yang komponennya diimplementasikan di React.js . Kami akan menggunakan dua tema global - gelap dan terang .

Dalam contoh ini, saya akan menggunakan modul create-react-context untuk membuat konteks.

Kami mulai dengan membuat folder di root proyek ( src / ) yang disebut tema-konteks . Struktur folder ini akan terlihat seperti ini:

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

Secara pribadi, saya selalu mulai dengan file index.js . Anda melakukan semua impor dan ekspor di awal, dan kemudian kepala Anda tidak sakit tentang mereka.

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

Selanjutnya, kita akan membuat konteks menggunakan createContext (maaf untuk permainan kata-kata), menggunakan modul dari sini .

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

Impor createContext , hancurkan ke Provider dan Consumer , dan ekspor mereka.

theme-context / constants.js

Semuanya sederhana di sini, kami membuat variabel kami agar tidak mencemari file utama.

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

Seperti yang saya katakan sebelumnya, aplikasi kita akan memiliki dua tema - terang dan gelap.

theme-context / ThemeProvider / ThemeProvider.js

Di sini kita akan berbicara tentang penyedia - komponen yang tersedia di setiap objek React.Context . Ini memungkinkan konsumen untuk mendengarkan dan menanggapi konteks yang berubah.

Dalam contoh kami, prop adalah theme yang akan diteruskan ke semua arus Provider ini 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.js

Dalam file ini kami akan bekerja dengan Konsumen - ini adalah komponen yang "mendengarkan, menunggu" untuk perubahan konteks. Anak dari komponen ini adalah suatu fungsi. Ini adalah suatu keharusan ketika menggunakan Consumer .

Fungsi ini menerima nilai-nilai konteks saat ini dan mengembalikan React Node , dengan kata lain, komponen.

Dari dokumentasi: nilai argumen (dalam kasus kami {theme => / * untuk memvisualisasikan sesuatu berdasarkan nilai konteks * /}) akan sama dengan theme orangtua terdekat di pohon Provider untuk konteks ini.

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

Di sini perlu diperhatikan hal-hal berikut:
Jika tema tidak dipilih secara eksplisit, kita perlu tema komponen yang akan dipilih secara otomatis, untuk ini saya menggunakan lodash dari lodash - defaultTo . Namun, fungsi ini dapat dicapai dengan banyak cara lain.

Itu saja, konteks tema siap digunakan!

Mari kita lihat bagaimana cara menerapkannya. Mari kita membuat komponen sederhana yang akan mendengarkan dan menanggapi konteks aplikasi kita.

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

Jadi, kami membungkus <App /> di penyedia, dan sekarang temanya telah tersedia untuk semua komponen-konsumen dalam aplikasi kami. Selanjutnya, <App /> mengembalikan <MyComponent /> , ini adalah , dan itu akan membuat komponen kita dan meneruskannya dengan tema aplikasi kita. Dan sudah memiliki topik sebagai argumen:

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

kita dapat menggunakannya saat membuat komponen
  const renderMyComponent = theme => { //      }; 

Kode kerja dapat ditemukan di sini .

Itu saja, saya harap Anda menemukan posting ini bermanfaat. Dalam posting berikutnya saya akan mencoba untuk membuat konteks media , yang fungsinya akan membantu kami memvisualisasikan komponen pada peralatan perangkat pengguna.

Terima kasih

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


All Articles