Μάθετε το React Context σε 5 λεπτά - Ένα σεμινάριο για αρχάριους

Το React's Context API έχει γίνει το εργαλείο διαχείρισης της κατάστασης για πολλούς, συχνά αντικαθιστώντας το Redux. Σε αυτό το γρήγορο σεμινάριο 5 λεπτών, θα δείτε μια εισαγωγή για το τι είναι το Περιεχόμενο και πώς να το χρησιμοποιήσετε!

Εάν θέλετε μια σωστή εισαγωγή σε αυτό το θέμα, μπορείτε να εγγραφείτε στη λίστα αναμονής για το επερχόμενο μάθημα React για προχωρημένους ή εάν είστε ακόμα αρχάριος, ρίξτε μια ματιά στο δωρεάν εισαγωγικό μάθημα για το React.

Σκεφτείτε αυτό το δέντρο, στο οποίο τα κάτω κουτιά αντιπροσωπεύουν ξεχωριστά στοιχεία:

Δέντρο συστατικών

Μπορούμε εύκολα να προσθέσουμε κατάσταση στα κάτω στοιχεία, αλλά μέχρι τώρα ο μόνος τρόπος για να μεταφέρουμε δεδομένα στον αδελφό ενός στοιχείου ήταν να μετακινήσουμε την κατάσταση σε ένα υψηλότερο στοιχείο και στη συνέχεια να τα μεταφέρουμε πίσω στον αδελφό μέσω στηριγμάτων.

Διαβίβαση δεδομένων μέσω στηριγμάτων

Εάν αργότερα ανακαλύψουμε ότι ο αδελφός του στοιχείου με κατάσταση χρειάζεται επίσης τα δεδομένα, πρέπει να σηκώσουμε ξανά την κατάσταση και να τα μεταφέρουμε προς τα κάτω:

Περνώντας κατάσταση κάτω από πολλαπλά επίπεδα

Ενώ αυτή η λύση λειτουργεί, τα προβλήματα ξεκινούν εάν ένα στοιχείο σε διαφορετικό κλάδο χρειάζεται τα δεδομένα:

Το πιο μακρινό στοιχείο απαιτεί δεδομένα

Σε αυτήν την περίπτωση, πρέπει να περάσουμε την κατάσταση από το ανώτερο επίπεδο της εφαρμογής σε όλα τα ενδιάμεσα στοιχεία σε αυτό που χρειάζεται τα δεδομένα στο κάτω μέρος, παρόλο που τα ενδιάμεσα επίπεδα δεν το χρειάζονται. Αυτή η κουραστική και χρονοβόρα διαδικασία είναι γνωστή ως γεωτρήσεις .

Διάτρηση στηρίγματος

Εδώ μπαίνει το Context API. Παρέχει έναν τρόπο διαβίβασης δεδομένων μέσω του δέντρου συστατικών μέσω ενός ζεύγους Provider-Consumer χωρίς να χρειάζεται να περάσει στηρίγματα σε κάθε επίπεδο. Σκεφτείτε το ως τα στοιχεία που παίζουν Catch with data - τα ενδιάμεσα στοιχεία μπορεί να μην γνωρίζουν καν ότι συμβαίνει κάτι:

Πλαίσιο σε δράση

Για να το αποδείξουμε αυτό, θα δημιουργήσουμε αυτήν την funky (και εξαιρετικά χρήσιμη) εικόνα εναλλαγής ημέρας-νύχτας.

Αν θέλετε να δείτε τον πλήρη κωδικό, φροντίστε να δείτε την παιδική χαρά Scrimba για αυτό το άρθρο.

Δημιουργία περιβάλλοντος

Αρχικά, δημιουργούμε ένα νέο πλαίσιο. Καθώς θέλουμε ολόκληρη η εφαρμογή να έχει πρόσβαση σε αυτό, πηγαίνουμε index.jsκαι τυλίγουμε την εφαρμογή ThemeContext.Provider.

Περνάμε επίσης το valueστήριγμα στον Πάροχο. Αυτό κρατά τα δεδομένα που θέλουμε να αποθηκεύσουμε. Προς το παρόν, απλώς έχουμε σκληρό κώδικα 'Day'.

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

Κατανάλωση περιβάλλοντος με τύπο περιβάλλοντος

Προς το παρόν, App.jsεπιστρέφουμε απλώς το στοιχείο.

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

Στόχος μας είναι να χρησιμοποιήσουμε πλαίσιο για να αλλάξετε τις ClassNames στο Image.jsαπό Dayσε Night, ανάλογα με το ποια εικόνα θέλουμε να καταστήσει. Για να το κάνουμε αυτό, προσθέτουμε μια στατική ιδιότητα στο στοιχείο που ονομάζεται ContextTypeκαι στη συνέχεια χρησιμοποιούμε την παρεμβολή συμβολοσειρών για να την προσθέσουμε στα classNames του στοιχείου.

Τώρα, τα classNames περιέχουν τη συμβολοσειρά από το valueστήριγμα. Σημείωση: Μετακόμισα ThemeContextστο δικό του αρχείο για να αποτρέψω ένα σφάλμα.

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; 

Περιεχόμενο. Καταναλωτής

Δυστυχώς, αυτή η προσέγγιση λειτουργεί μόνο με στοιχεία που βασίζονται στην τάξη. Εάν έχετε μάθει ήδη για τα Hooks in React, θα γνωρίζετε ότι μπορούμε να κάνουμε σχεδόν οτιδήποτε με λειτουργικά συστατικά αυτές τις μέρες. Επομένως, για καλό μέτρο, πρέπει να μετατρέψουμε τα στοιχεία μας σε λειτουργικά στοιχεία και στη συνέχεια να χρησιμοποιήσουμε το ThemeContext.Consumerστοιχείο για να μεταφέρουμε πληροφορίες μέσω της εφαρμογής.

Αυτό γίνεται με την αναδίπλωση των στοιχείων μας σε μια παρουσία και εντός αυτής (όπου childrenπηγαίνει), παρέχοντας μια λειτουργία που επιστρέφει τα στοιχεία. Αυτό χρησιμοποιεί το μοτίβο "render prop" όπου παρέχουμε μια κανονική λειτουργία ως παιδί που επιστρέφει κάποιο JSX για απόδοση.

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; 

Σημείωση: Πρέπει επίσης να τυλίξουμε το στοιχείο - αυτό μας επιτρέπει να προσθέσουμε λειτουργικότητα στο κουμπί αργότερα.

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

Εξαγωγή παροχέα περιβάλλοντος

Αυτήν τη στιγμή περνάμε μια κωδικοποιημένη τιμή μέσω του παρόχου, ωστόσο, στόχος μας είναι να αλλάξουμε μεταξύ νύχτας και ημέρας με το κουμπί μας.

Αυτό απαιτεί τη μεταφορά του Παροχέα μας σε ένα ξεχωριστό αρχείο και την τοποθέτησή του στο δικό του στοιχείο, σε αυτήν την περίπτωση, που ονομάζεται 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 }; 

Σημείωση: η ιδιότητα value αντιμετωπίζεται τώρα στο νέο αρχείο ThemeContext.js και, ως εκ τούτου, θα πρέπει να αφαιρεθεί από το index.js.

Αλλαγή περιβάλλοντος

Για να συνδέσετε το κουμπί, προσθέτουμε πρώτα την κατάσταση σε 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 }; 

Στη συνέχεια, προσθέτουμε μια μέθοδο εναλλαγής μεταξύ ημέρας και νύχτας:

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

Τώρα αλλάζουμε την valueιδιότητά μας this.state.themeέτσι ώστε να επιστρέφει τις πληροφορίες από την πολιτεία.

 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

Αυτό το παράδειγμα είναι πολύ απλό και πιθανότατα θα ήταν πιο εύκολο να βάλετε κατάσταση στην εφαρμογή και να το μεταβιβάσετε μέσω στηριγμάτων. Ωστόσο, ελπίζουμε να δείχνει τη δύναμη να έχουν Καταναλωτές οι οποίοι μπορούν να έχουν πρόσβαση σε δεδομένα ανεξάρτητα από τα στοιχεία που βρίσκονται πάνω τους στο δέντρο.

Για να μάθετε περισσότερα σχετικά με το React Context και άλλες εξαιρετικές δυνατότητες του React, μπορείτε να εγγραφείτε στη λίστα αναμονής για το επερχόμενο μάθημα React για προχωρημένους. Ή αν ψάχνετε για πιο φιλικούς για αρχάριους, μπορείτε να δείτε το δωρεάν εισαγωγικό μάθημα στο React.

Καλή κωδικοποίηση :)