Πώς να δημιουργήσετε μια εφαρμογή αναζήτησης ταινιών χρησιμοποιώντας το React Hooks

Φωτογραφία από τον Bundo Kim στο Unsplash

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

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

Ξέρω ότι κάποιοι θα μπορούσαν να πουν "Άλλο άρθρο για γάντζους, πραγματικά;" και σε αυτούς, λέω "Ναι ... ναι και υπάρχουν περισσότερα από πού προέρχονται". Για αυτό το άρθρο, θα χτίζουμε μια πολύ απλή εφαρμογή χρησιμοποιώντας τα γάντζους. Στην ουσία, δεν πρόκειται να χρησιμοποιήσουμε κανένα στοιχείο τάξης σε αυτήν την εφαρμογή. Και θα εξηγήσω πώς λειτουργούν μερικά από τα API και πώς θα πρέπει να χρησιμοποιούνται σε οποιαδήποτε εφαρμογή που θα μπορούσαμε να οικοδομήσουμε.

Ακολουθεί μια εικόνα για το πώς θα εμφανιστεί η εφαρμογή όταν τελειώσουμε:

Ξέρω, το όνομα είναι πραγματικά δημιουργικό ...

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

  • Κόμβος (≥ 6)
  • Ένας δροσερός κειμενογράφος
  • Ένα κλειδί API από την OMDB (Μπορείτε να το αποκτήσετε εδώ ή να χρησιμοποιήσετε το δικό μου)

Μεγάλη, μόλις το έχουμε, τότε το επόμενο βήμα είναι να ρυθμίσετε την εφαρμογή React. Για αυτό το σεμινάριο θα χρησιμοποιήσουμε το create-react-app - είναι ένα πραγματικά εκπληκτικό εργαλείο για τη δημιουργία μιας εφαρμογής React χωρίς να χρειάζεται να αντιμετωπίσετε όλες τις διαμορφώσεις που έρχονται με ξεκινώντας από το μηδέν. Μπορείτε να δημιουργήσετε μια νέα εφαρμογή πληκτρολογώντας:

Αν προτιμάτε να αντιγράψετε και να επικολλήσετε τότε:

create-react-app hooked # "hooked" είναι το όνομα της εφαρμογής μας
# αν δεν έχετε εγκαταστήσει την εφαρμογή δημιουργίας-αντίδρασης, πληκτρολογήστε τα παρακάτω
npm install -g δημιουργία-αντιδρά-app

Μόλις γίνει αυτό θα πρέπει να έχουμε ένα φάκελο που ονομάζεται "Hooked" με μια δομή καταλόγου όπως φαίνεται παρακάτω:

ΑΡΧΙΚΗ ΔΟΜΗ ΕΡΓΟΥ

Θα έχουμε 4 στοιχεία σε αυτή την εφαρμογή, οπότε ας περιγράψουμε το καθένα και τη λειτουργικότητά του:

  • App.js - Θα είναι το γονικό στοιχείο για το άλλο 3. Θα περιέχει επίσης τη λειτουργία που χειρίζεται το αίτημα API και θα έχει μια λειτουργία που καλεί το API κατά την αρχική απόδοση της συνιστώσας.
  • Header.js - Ένα απλό στοιχείο που μετατρέπει την κεφαλίδα της εφαρμογής και δέχεται ένα υπόβαθρο τίτλου
  • Movie.js - Κάνει κάθε ταινία. Το αντικείμενο ταινίας απλά μεταφέρεται σε αυτό ως στηρίγματα.
  • Search.js - Περιέχει μια φόρμα με το στοιχείο εισόδου και το κουμπί αναζήτησης, περιέχει λειτουργίες που χειρίζονται το στοιχείο εισόδου και επαναφέρει το πεδίο, και περιέχει επίσης μια λειτουργία που καλεί τη λειτουργία αναζήτησης που περνάει ως στηρίγματα σε αυτήν.

Ας αρχίσουμε να δημιουργούμε στον κατάλογο src ένα νέο φάκελο και να ονομάζουμε τα εξαρτήματα γιατί εκεί θα είναι όλα τα στοιχεία μας. Στη συνέχεια, θα μετακινήσουμε το αρχείο App.js σε αυτόν το φάκελο. Στη συνέχεια, θα δημιουργήσουμε το στοιχείο Header. Δημιουργήστε ένα αρχείο που ονομάζεται Header.js και προσθέστε τον ακόλουθο κώδικα σε αυτό:

εισαγωγή Αντιδρά από "αντιδρά";
const Header = (στηρίγματα) => {
  ΕΠΙΣΤΡΟΦΗ (
    
      

{props.text}        ) · },

εξαγωγή προεπιλεγμένης κεφαλίδας.

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

Ας μην ξεχάσουμε να ενημερώσουμε την εισαγωγή στο αρχείο index.js:

εισαγωγή Αντιδρά από "αντιδρά";
εισαγωγή του ReactDOM από το 'react-dom';
εισαγωγή './index.css'.
εισαγωγή εφαρμογής από './components/App'; // αυτό άλλαξε
εισαγωγή * ως serviceWorker από το "./serviceWorker";
ReactDOM.render (, document.getElementById ('root'));
// Αν θέλετε η εφαρμογή σας να λειτουργεί χωρίς σύνδεση και να φορτώνεται πιο γρήγορα, μπορείτε να την αλλάξετε
// unregister () για να εγγραφείτε () παρακάτω. Σημειώστε ότι αυτό έρχεται με κάποιες παγίδες.
// Μάθετε περισσότερα σχετικά με τους εργαζόμενους στις υπηρεσίες: http://bit.ly/CRA-PWA
serviceWorker.unregister ();

Και ενημερώστε επίσης το App.css με αυτά τα στυλ (όχι υποχρεωτικά):

.App {
  κείμενο-ευθυγράμμιση: κέντρο;
}}
.App-header {
  χρώμα φόντου: # 282c34;
  ύψος: 70px;
  οθόνη: flex;
  ευέλικτη κατεύθυνση: στήλη.
  ευθυγράμμιση-στοιχεία: κέντρο
  justify-content: center;
  μέγεθος γραμματοσειράς: calc (10px + 2vmin);
  άσπρο χρώμα;
  padding: 20px;
  δρομέας: δείκτης;
}}
.spinner {
  ύψος: 80px;
  περιθώριο: αυτόματη;
}}
.App-intro {
  μέγεθος γραμματοσειράς: μεγάλο;
}}
/ * νέο css για την ταινία * /
* {
  μέγεθος κιβωτίου: πλαίσιο-πλαίσιο?
}}
.movies {
  οθόνη: flex;
  flex-wrap: wrap;
  ευέλικτη κατεύθυνση: σειρά?
}}
.App-header h2 {
  περιθώριο: 0;
}}
.add-ταινίες {
  κείμενο-ευθυγράμμιση: κέντρο;
}}
. κουμπί {add-movies} {
  μέγεθος γραμματοσειράς: 16px;
  padding: 8px;
  περιθώριο: 0 10px 30px 10px;
}}
.movie {
  padding: 5px 25px 10px 25px;
  μέγιστο πλάτος: 25%.
}}
.μήνυμα λάθους {
  περιθώριο: αυτόματη;
  γραμματοσειρά-βάρος: έντονα.
  χρώμα: rgb (161, 15, 15);
}}
.Αναζήτηση {
  οθόνη: flex;
  ευέλικτη κατεύθυνση: σειρά?
  flex-wrap: wrap;
  justify-content: center;
  περιθώριο-κορυφή: 10px;
}}
είσοδος [type = "υποβάλλει"]] {
  padding: 5px;
  Χρώμα φόντου: διαφανές.
  χρωμα μαυρο;
  σύνορα: 1px μαύρο?
  πλάτος: 80px;
  περιθώριο-αριστερά: 5px;
  δρομέας: δείκτης;
}}
είσοδος [type = "υποβάλω"]: hover {
  χρώμα φόντου: # 282c34;
  χρώμα: αντίκες;
}}
. αναζήτηση> εισαγωγή [τύπου = "κείμενο"] {
  πλάτος: 40%.
  min-πλάτος: 170px;
}}
@media screen και (min-width: 694px) και (max-width: 915px) {
  .movie {
    μέγιστο πλάτος: 33%.
  }}
}}
@media screen και (min-width: 652px) και (max-width: 693px) {
  .movie {
    μέγιστο πλάτος: 50%.
  }}
}}
@media οθόνη και (max-width: 651px) {
  .movie {
    μέγιστο πλάτος: 100%.
    περιθώριο: αυτόματη;
  }}
}}

Μόλις το έχουμε, το επόμενο πράγμα είναι να δημιουργήσουμε το στοιχείο της ταινίας. Αυτό θα το κάνουμε δημιουργώντας ένα αρχείο που ονομάζεται Movie.js και προσθέτοντας τον ακόλουθο κώδικα:

εισαγωγή Αντιδρά από "αντιδρά";
const DEFAULT_PLACEHOLDER_IMAGE =
  "https://m.media-amazon.com/images/M/[email protected]@__V1_SX300.jpg";
const Ταινία = ({movie}) => {
  const poster =
    movie.Poster === "N / A"; DEFAULT_PLACEHOLDER_IMAGE: movie.Poster;
  ΕΠΙΣΤΡΟΦΗ (
    
      

{movie.Title}       
                      

({movie.Year}))        ) · },

εξαγωγή προεπιλεγμένης ταινίας.

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

Τώρα θα δημιουργήσουμε το στοιχείο αναζήτησης. Αυτό το μέρος είναι συναρπαστικό γιατί στο παρελθόν, για να χειριστούμε την εσωτερική κατάσταση, θα έπρεπε να δημιουργήσουμε ένα συστατικό κλάσης ... αλλά όχι πια! Επειδή με τα άγκιστρα μπορούμε να έχουμε ένα λειτουργικό συστατικό να χειρίζεται τη δική του εσωτερική κατάσταση. Ας δημιουργήσουμε ένα αρχείο με όνομα Search.js και σε αυτό το αρχείο, θα προσθέσουμε τον ακόλουθο κώδικα:

Εισαγωγή React, {useState} από το "react".
const Αναζήτηση = (στηρίγματα) => {
  const [searchValue, setSearchValue] = useState ("");
const χειρισμόςSearchInputChanges = (e) => {
    setSearchValue (e.target.value);
  }}
const resetInputField = () => {
    setSearchValue ("")
  }}
const callSearchFunction = (e) => {
    e.preventDefault ();
    props.search (searchValue);
    resetInputField ();
  }}
ΕΠΙΣΤΡΟΦΗ (
      
        <είσοδος           value = {searchValue}           onChange = {handleSearchInputChanges}           type = "text"         />                     ) · }}
εξαγωγή προεπιλεγμένης αναζήτησης

Αυτό είναι τόσο συναρπαστικό !!! Είμαι βέβαιος ότι μόλις είδατε το πρώτο API hooks που πρόκειται να χρησιμοποιήσουμε και ονομάζεται useState. Όπως υποδηλώνει το όνομα, μας επιτρέπει να προσθέτουμε στοιχεία React state για λειτουργία. Το άγκιστρο useState δέχεται ένα όρισμα που είναι η αρχική κατάσταση και στη συνέχεια επιστρέφει έναν πίνακα που περιέχει την τρέχουσα κατάσταση (ισοδύναμο με αυτό το statestate για τα συστατικά της κλάσης) και μια συνάρτηση για την ενημέρωσή του (ισοδύναμη με αυτή .setState).

Στην περίπτωσή μας, περάσαμε την τρέχουσα κατάσταση μας ως την τιμή για το πεδίο εισαγωγής αναζήτησης. Όταν καλείται το συμβάν onChange, καλείται η λειτουργία handleSearchInputChanges, η οποία καλεί τη λειτουργία ενημέρωσης κατάστασης με τη νέα τιμή. Η συνάρτηση resetInputField βασικά ονομάζεται συνάρτηση ενημέρωσης κατάστασης (setSearchValue) με μια κενή συμβολοσειρά για να καθαρίσει το πεδίο εισαγωγής. Ελέγξτε αυτό για να μάθετε περισσότερα σχετικά με το API useState.

Τέλος, θα ενημερώσουμε το αρχείο App.js με τον ακόλουθο κώδικα:

εισαγωγή React, {useState, useEffect} από το "αντιδρά";
εισαγωγή "../App.css";
Εισαγωγή κεφαλίδας από "./Header";
εισαγωγή ταινίας από "./Movie";
εισαγωγή από την αναζήτηση "./Search";
const MOVIE_API_URL = "https://www.omdbapi.com/?s=man&apikey=4a3b711b"; // θα πρέπει να το αντικαταστήσετε με το δικό σας
const App = () => {
  const [φόρτωση, setLoading] = useState (true);
  const [ταινίες, setMovies] = useState ([]);
  const [errorMessage, setErrorMessage] = useState (μηδέν);
useEffect (() => {
    fetch (MOVIE_API_URL)
      .then (απάντηση => response.json ())
      .then (jsonResponse => {
        setMovies (jsonResponse.Search);
        setLoading (ψευδές);
      });
  }, []).
const αναζήτηση = searchValue => {
    setLoading (true);
    setErrorMessage (null);
fetch (`https://www.omdbapi.com/?s=$ {searchValue} & apikey = 4a3b711b`)
      .then (απάντηση => response.json ())
      .then (jsonResponse => {
        αν (jsonResponse.Response === "True") {
          setMovies (jsonResponse.Search);
          setLoading (ψευδές);
        } else {
          setErrorMessage (jsonResponse.Error);
          setLoading (ψευδές);
        }}
      });
  },
ΕΠΙΣΤΡΟΦΗ (
    
      
      <Αναζήτηση αναζήτησης = {search} />       

Κοινή χρήση μερικών από τις αγαπημένες μας ταινίες       

        {loading &&! errorMessage? (           φόρτωση ...
         ) : μήνυμα λάθους ? (
          
{errorMessage}         ): (           movies.map ((ταινία, ευρετήριο) => (             <Κλειδί ταινίας = {`$ {index} - $ {movie.Title}}} movie = {movie} />           ))         )}               ) · },
εξαγωγή προεπιλεγμένης εφαρμογής?

Ας δούμε τον κώδικα: χρησιμοποιούμε 3 λειτουργίες usestat, έτσι ναι, μπορούμε να έχουμε πολλαπλές λειτουργίες χρηστών σε ένα στοιχείο. Το πρώτο χρησιμοποιείται για να χειριστεί την κατάσταση φόρτωσης (κάνει το κείμενο "φόρτωση ..." όταν η φόρτωση έχει οριστεί ως αληθής). Το δεύτερο χρησιμοποιείται για τη διαχείριση της σειράς ταινιών που έχει ληφθεί από το διακομιστή. Και τέλος, το τρίτο χρησιμοποιείται για να χειριστεί τυχόν σφάλματα που μπορεί να προκύψουν κατά την πραγματοποίηση του αιτήματος API.

Και μετά από αυτό, συναντάμε το δεύτερο API hooks που χρησιμοποιούμε στην εφαρμογή: το άγκιστρο useEffect. Αυτό το άγκιστρο βασικά σας επιτρέπει να εκτελείτε παρενέργειες στα εξαρτήματα της λειτουργίας σας. Με παρενέργειες εννοούμε πράγματα όπως η ανάκτηση δεδομένων, οι συνδρομές και οι χειρωνακτικοί χειρισμοί DOM. Το καλύτερο μέρος για αυτό το άγκιστρο είναι αυτό το απόσπασμα από τα επίσημα έγγραφα του React:

Αν είστε εξοικειωμένοι με τις μεθόδους κύκλου ζωής του React, μπορείτε να σκεφτείτε το useEffect Hook ως componentDidMount, componentDidUpdate και componentWillUnmount συνδυαστικά.

Αυτό συμβαίνει επειδή το useEffect αποκαλείται μετά την πρώτη rendering (componentDidMount) και επίσης μετά από κάθε ενημέρωση (componentDidUpdate).

Ξέρω ότι μπορεί να αναρωτιέστε πώς αυτό είναι παρόμοιο με το componentDidMount αν αποκαλείται μετά από κάθε ενημέρωση. Λοιπόν, επειδή η λειτουργία useEffect δέχεται δύο επιχειρήματα, τη συνάρτηση που θέλετε να εκτελέσετε και ένα δεύτερο όρισμα που είναι ένας πίνακας. Σε αυτήν τη συστοιχία, περάσαμε μόνο μια τιμή που λέει στο React να παρακάμπτει την εφαρμογή ενός αποτελέσματος αν η τιμή που πέρασε δεν έχει αλλάξει.

Σύμφωνα με τα έγγραφα, είναι παρόμοια με όταν προσθέτουμε μια υπό όρους δήλωση στο componentDidUpdate:

// για τα τμήματα κλάσης
componentDidUpdate (prevProps, prevState) {
  αν (prevState.count! == this.state.count) {
    document.title = `Κάνατε κλικ στο $ {this.state.count} times`;
  }}
}}
// χρησιμοποιώντας γάντζους θα γίνει
useEffect (() => {
  document.title = `Κάνατε κλικ στο $ {count} φορές.
}, [μετρώ]); // Εκτελέστε εκ νέου το εφέ αν αλλάξει η μέτρηση

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

Όπως μπορείτε να δείτε, έχουμε 3 χρήσιμες λειτουργίες που σχετίζονται κάπως και πρέπει να είναι δυνατόν να συνδυαστούν με κάποιο τρόπο. Ευτυχώς, η ομάδα της React μας έχει καλύψει επειδή έκαναν ένα άγκιστρο που βοηθά με αυτό - και αυτό το άγκιστρο καλείται useReducer. Ας μετατρέψουμε το στοιχείο εφαρμογής μας για να χρησιμοποιήσουμε τον νέο μας γάντζο, έτσι ώστε το App.js μας θα μοιάζει με αυτό:

εισαγωγή React, {useReducer, useEffect} από το "αντιδρά";
εισαγωγή "../App.css";
Εισαγωγή κεφαλίδας από "./Header";
εισαγωγή ταινίας από "./Movie";
εισαγωγή από την αναζήτηση "./Search";
const MOVIE_API_URL = "https://www.omdbapi.com/?s=man&apikey=4a3b711b";
const initialState = {
  φόρτωση: αλήθεια,
  ταινίες: [],
  errorMessage: null
},
const reducer = (κατάσταση, δράση) => {
  διακόπτης (action.type) {
    περίπτωση "SEARCH_MOVIES_REQUEST":
      ΕΠΙΣΤΡΟΦΗ {
        ...κατάσταση,
        φόρτωση: αλήθεια,
        errorMessage: null
      },
    περίπτωση "SEARCH_MOVIES_SUCCESS":
      ΕΠΙΣΤΡΟΦΗ {
        ...κατάσταση,
        φόρτωση: ψευδής,
        ταινίες: action.payload
      },
    περίπτωση "SEARCH_MOVIES_FAILURE":
      ΕΠΙΣΤΡΟΦΗ {
        ...κατάσταση,
        φόρτωση: ψευδής,
        errorMessage: action.error
      },
    Προκαθορισμένο:
      κατάσταση επιστροφής;
  }}
},
const App = () => {
  const [κατάσταση, αποστολή] = useReducer (reductor, initialState);
useEffect (() => {
    fetch (MOVIE_API_URL)
      .then (απάντηση => response.json ())
      .then (jsonResponse => {
        επιστολή({
          πληκτρολογήστε: "SEARCH_MOVIES_SUCCESS",
          ωφέλιμο φορτίο: jsonResponse.Search
        });
      });
  }, []).
const αναζήτηση = searchValue => {
    επιστολή({
      πληκτρολογήστε: "SEARCH_MOVIES_REQUEST"
    });
fetch (`https://www.omdbapi.com/?s=$ {searchValue} & apikey = 4a3b711b`)
      .then (απάντηση => response.json ())
      .then (jsonResponse => {
        αν (jsonResponse.Response === "True") {
          επιστολή({
            πληκτρολογήστε: "SEARCH_MOVIES_SUCCESS",
            ωφέλιμο φορτίο: jsonResponse.Search
          });
        } else {
          επιστολή({
            πληκτρολογήστε: "SEARCH_MOVIES_FAILURE",
            σφάλμα: jsonResponse.Error
          });
        }}
      });
  },
const {ταινίες, errorMessage, φόρτωση} = κατάσταση;
ΕΠΙΣΤΡΟΦΗ (
    
      
      <Αναζήτηση αναζήτησης = {search} />       

Κοινή χρήση μερικών από τις αγαπημένες μας ταινίες       

        {loading &&! errorMessage? (            φόρτωση ...         ) : μήνυμα λάθους ? (           
{errorMessage}         ): (           movies.map ((ταινία, ευρετήριο) => (             <Κλειδί ταινίας = {`$ {index} - $ {movie.Title}}} movie = {movie} />           ))         )}               ) · },
εξαγωγή προεπιλεγμένης εφαρμογής?

Έτσι, αν όλα πάνε καλά, τότε δεν θα πρέπει να δούμε καμία αλλαγή στη συμπεριφορά της εφαρμογής. Τώρα ας δούμε πώς λειτουργεί το γάντζο useReducer.

Ο γάντζος παίρνει 3 επιχειρήματα, αλλά για την περίπτωση χρήσης μας θα χρησιμοποιούμε μόνο 2. Μια τυπική χρήση γάντζοReducer θα μοιάζει με αυτό:

const [κατάσταση, αποστολή] = useReducer (
    περιστέλλων,
    αρχική κατάσταση
 ) ·

Το επιχείρημα του μειωτήρα είναι παρόμοιο με αυτό που χρησιμοποιούμε στο Redux, το οποίο μοιάζει με αυτό:

const reducer = (κατάσταση, δράση) => {
  διακόπτης (action.type) {
    περίπτωση "SEARCH_MOVIES_REQUEST":
      ΕΠΙΣΤΡΟΦΗ {
        ...κατάσταση,
        φόρτωση: αλήθεια,
        errorMessage: null
      },
    περίπτωση "SEARCH_MOVIES_SUCCESS":
      ΕΠΙΣΤΡΟΦΗ {
        ...κατάσταση,
        φόρτωση: ψευδής,
        ταινίες: action.payload
      },
    περίπτωση "SEARCH_MOVIES_FAILURE":
      ΕΠΙΣΤΡΟΦΗ {
        ...κατάσταση,
        φόρτωση: ψευδής,
        errorMessage: action.error
      },
    Προκαθορισμένο:
      κατάσταση επιστροφής;
  }}
},

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

Ένα άλλο πράγμα που πρέπει να σημειώσουμε είναι ότι στο useEffect μας, αποστέλλουμε τώρα μια ενέργεια με το ωφέλιμο φορτίο όπως η σειρά ταινιών που παίρνουμε από το διακομιστή. Επίσης, στη λειτουργία αναζήτησης, εκτελούμε πραγματικά τρεις διαφορετικές ενέργειες.

  • Μια ενέργεια είναι η ενέργεια SEARCH_MOVIES_REQUEST που ενημερώνει το αντικείμενο του κράτους μας, κάνοντας φόρτωση = true και errorMessage = null.
  • Εάν η αίτηση είναι επιτυχής, τότε θα αποστείλουμε μια άλλη ενέργεια με τον τύπο SEARCH_MOVIES_SUCCESS που ενημερώνει το αντικείμενο κατάστασης μας κάνοντας φόρτωση = ψευδής και ταινίες = action.payload όπου το ωφέλιμο φορτίο είναι η σειρά ταινιών που έχει πάρει από την OMDB.
  • Εάν υπάρχει κάποιο σφάλμα, θα στείλουμε διαφορετική ενέργεια με τον τύπο SEARCH_MOVIES_FAILURE που ενημερώνει το αντικείμενο του κράτους μας φορτώντας = false και errorMessage = action.error όπου το action.error είναι το μήνυμα σφάλματος που έχει πάρει από το διακομιστή.

Για να μάθετε περισσότερα σχετικά με τη χρήση του γάντζου Reducer μπορείτε να δείτε την επίσημη τεκμηρίωση.

Τυλίγοντας

Ουάου!!! Έχουμε προχωρήσει πολύ και είμαι βέβαιος ότι είστε τόσο ενθουσιασμένοι όσο είμαι για τις δυνατότητες των γάντζων. Για μένα προσωπικά, είναι πολύ πιο εύκολο να εισαγάγει τους αρχάριους στο React, γιατί δεν χρειάζεται να εξηγώ πώς δουλεύουν τα μαθήματα ή πώς λειτουργεί αυτό ή πώς λειτουργεί το bind στην JS, κάτι που είναι φοβερό IMO.

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

ΣΗΜΕΙΩΣΗ: Αυτό το άρθρο δεν σχετίζεται με το προηγούμενο για το Webpack, ένα επόμενο άρθρο γι 'αυτό είναι ήδη υπό κατασκευή .

Αυτός είναι ο σύνδεσμος προς το repo GitHub για αυτό το άρθρο.