Belajar Konteks React dalam 5 Minit - Tutorial Seorang Pemula

React's Context API telah menjadi alat pilihan negeri untuk banyak pilihan, seringkali menggantikan Redux sama sekali. Dalam tutorial 5 minit pantas ini, anda akan melihat pengenalan tentang apa itu Konteks dan cara menggunakannya!

Sekiranya anda mahukan pengenalan yang tepat untuk subjek ini, anda boleh menyertai senarai menunggu kursus React lanjutan saya yang akan datang, atau jika anda masih pemula, lihat kursus perkenalan percuma saya mengenai React.

Pertimbangkan pokok ini, di mana kotak bawah mewakili komponen yang berasingan:

Pokok komponen

Kita dapat menambahkan keadaan ke komponen bawah dengan mudah, tetapi hingga sekarang satu-satunya cara untuk menyampaikan data ke saudara komponen adalah memindahkan keadaan ke komponen yang lebih tinggi dan kemudian meneruskannya kembali ke saudara melalui alat peraga.

Menyampaikan data melalui alat peraga

Sekiranya kita kemudian mengetahui bahawa saudara komponen dengan keadaan juga memerlukan data, kita harus menaikkan kembali keadaan, dan mengembalikannya ke bawah:

Melewati keadaan melalui pelbagai peringkat

Walaupun penyelesaian ini berfungsi, masalah akan timbul sekiranya komponen pada cabang lain memerlukan data:

Komponen yang lebih jauh memerlukan data

Dalam kes ini, kita perlu melewati keadaan dari tingkat atas aplikasi melalui semua komponen perantara ke komponen yang memerlukan data di bahagian bawah, walaupun tahap perantara tidak memerlukannya. Proses yang membosankan dan memakan masa ini dikenali sebagai prop drilling .

Penggerudian prop

Di sinilah API Konteks masuk. Ini menyediakan cara untuk menyebarkan data melalui pohon komponen melalui pasangan Penyedia-Pengguna tanpa harus melewati alat peraga ke bawah setiap tingkat. Anggaplah ia sebagai komponen bermain Catch with data - komponen perantara mungkin tidak "tahu" bahawa ada sesuatu yang berlaku:

Konteks dalam tindakan

Untuk menunjukkannya, kami akan membuat gambar beralih dari hari ke malam yang funky (dan sangat berguna) ini.

Sekiranya anda ingin melihat kod penuh, pastikan untuk melihat taman permainan Scrimba untuk artikel ini.

Buat Konteks

Untuk memulakan, kami membuat Konteks baru. Oleh kerana kami mahu seluruh aplikasi mempunyai akses ke ini, kami pergi ke index.jsdan membungkus aplikasi tersebut ThemeContext.Provider.

Kami juga memberikan valuepenyokong kepada Penyedia kami. Ini menyimpan data yang ingin kita simpan. Buat masa ini, kami hanya menggunakan kod keras 'Day'.

import React from "react"; import ReactDOM from "react-dom"; import ThemeContext from "./themeContext"; import App from "./App"; ReactDOM.render(   , document.getElementById("root") ); 

Menggunakan Konteks dengan Jenis konteks

Pada masa ini, di App.js, kita hanya mengembalikan komponennya.

import React from "react"; import Image from "./Image"; class App extends React.Component { render() { return ( ); } } export default App; 

Matlamat kami adalah menggunakan Konteks untuk menukar nama kelas Image.jsdari Daymenjadi Night, bergantung pada gambar mana yang ingin kami hasilkan . Untuk melakukan ini, kami menambahkan sifat statik ke komponen kami yang disebut ContextTypedan kemudian menggunakan interpolasi rentetan untuk menambahkannya ke classNames dalam komponen.

Sekarang, classNames mengandungi rentetan dari alat valueperaga. Catatan: Saya telah berpindah ThemeContextke failnya sendiri untuk mengelakkan bug.

import React from "react"; import Button from "./Button"; import ThemeContext from "./themeContext"; class Image extends React.Component { render() { const theme = this.context; return ( ); } } Image.contextType = ThemeContext; export default Image; 

Konteks. Pengguna

Malangnya, pendekatan ini hanya berfungsi dengan komponen berdasarkan kelas. Sekiranya anda sudah mengetahui mengenai Hooks in React, anda akan tahu bahawa kita boleh melakukan apa sahaja dengan komponen fungsional hari ini. Jadi untuk langkah yang baik, kita harus menukar komponen kita menjadi komponen berfungsi dan kemudian menggunakan ThemeContext.Consumerkomponen untuk menyampaikan maklumat melalui aplikasi.

Ini dilakukan dengan membungkus elemen-elemen kita dalam contoh dan di dalamnya (ke mana childrensaja), menyediakan fungsi yang mengembalikan elemen. Ini menggunakan corak "render prop" di mana kami menyediakan fungsi biasa sebagai anak yang mengembalikan beberapa JSX untuk diberikan.

import React from "react"; import Button from "./Button"; import ThemeContext from "./themeContext"; function Image(props) { // We don't need this anymore // const theme = this.context return (  {theme => ( )}  ); } // We don't need this anymore // Image.contextType = ThemeContext; export default Image; 

Catatan: Kami juga perlu membungkus komponen - ini membolehkan kami menambah fungsi pada butang kemudian.

import React from "react"; import ThemeContext from "./themeContext"; function Button(props) { return (  {context => (  Switch  ?   ?   )}  ); } export default Button; 

Ekstrak Penyedia Konteks

We are currently passing a hard-coded value down through the Provider, however, our goal is to switch between night and day with our button.

This requires moving our Provider to a separate file and putting it in its own component, in this case, called ThemeContextProvider.

import React, { Component } from "react"; const { Provider, Consumer } = React.createContext(); class ThemeContextProvider extends Component { render() { return {this.props.children}; } } export { ThemeContextProvider, Consumer as ThemeContextConsumer }; 

Note: the value property is now being handled in the new file ThemeContext.js, and should, therefore, be removed from index.js.

Changing Context

To wire up the button, we first add state to ThemeContextProvider:

import React, { Component } from "react"; const { Provider, Consumer } = React.createContext(); // Note: You could also use hooks to provide state and convert this into a functional component. class ThemeContextProvider extends Component { state = { theme: "Day" }; render() { return {this.props.children}; } } export { ThemeContextProvider, Consumer as ThemeContextConsumer }; 

Next, we add a method for switching between day and night:

toggleTheme = () => { this.setState(prevState => { return { theme: prevState.theme === "Day" ? "Night" : "Day" }; }); }; 

Now we change our value property to this.state.theme so that it returns the info from state.

 render() { return {this.props.children}; } } 

Next, we change value to an object containing {theme: this.state.theme, toggleTheme: this.toggleTheme}, and update all the places where we use a single value to look for theme in an object. This means that every theme becomes context and every reference to theme as value becomes context.theme.

Finally, we tell the button to listen for the onClick event and then fire context.toggleTheme - this updates the Consumers which are using the state from the Provider. The code for the button looks like this:

import React from "react"; import { ThemeContextConsumer } from "./themeContext"; function Button(props) { return (  {context => (  Switch  ?   ?   )}  ); } export default Button; 

Our button now switches the image between night and day in one click!

Context caveats

Like all good things in code, there are some caveats to using Context:

  • Don't use Context to avoid drilling props down just one or two layers. Context is great for managing state which is needed by large portions of an application. However, prop drilling is faster if you are just passing info down a couple of layers.

  • Avoid using Context to save state that should be kept locally. So if you need to save a user's form inputs, for example, use local state and not Context.

  • Always wrap the Provider around the lowest possible common parent in the tree - not the app's highest-level component. No need for overkill.

  • Lastly, if you pass an object as your value prop, monitor performance and refactor as necessary. This probably won't be needed unless a drop in performance is noticeable.

Wrap up

Contoh ini cukup mudah dan mungkin lebih mudah untuk memasukkan keadaan dalam aplikasi dan menyampaikannya melalui alat peraga. Walau bagaimanapun, diharapkan dapat menunjukkan kehebatan pengguna yang dapat mengakses data secara bebas daripada komponen di atasnya di dalam pokok.

Untuk mengetahui lebih lanjut mengenai React Context dan ciri hebat React yang lain, anda boleh menyertai senarai menunggu kursus React lanjutan saya yang akan datang. Atau jika anda mencari yang lebih mesra pemula, anda boleh melihat kursus perkenalan percuma saya di React.

Selamat pengekodan :)