Πώς να γίνετε επαγγελματίας με το React setState () σε 10 λεπτά

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

Απλά διαβάστε και διασκεδάστε!

Πάρτε λοιπόν ένα φλιτζάνι καφέ και συνεχίστε να διαβάζετε! ;

Βασικές έννοιες του setState ()

Το React Components σάς επιτρέπει να διαχωρίζετε το περιβάλλον εργασίας χρήστη (UI) σε ανεξάρτητα, επαναχρησιμοποιήσιμα κομμάτια, ώστε να μπορείτε να σκεφτείτε κάθε κομμάτι μεμονωμένα.

Εννοιολογικά, τα στοιχεία είναι σαν λειτουργίες JavaScript. Δέχονται αυθαίρετες εισόδους (ονομάζονται «στηρίγματα») και επιστρέφουν στοιχεία React που περιγράφουν τι πρέπει να εμφανίζεται στην οθόνη.

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

Είτε δηλώνετε ένα στοιχείο ως συνάρτηση είτε ως κλάση, δεν πρέπει ποτέ να τροποποιεί τα δικά του στηρίγματα.

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

Φυσικά, οι διεπαφές χρήστη είναι δυναμικές και αλλάζουν με την πάροδο του χρόνου. Γι ' stateαυτό δημιουργήθηκε.

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

Τα στοιχεία που ορίζονται ως τάξεις έχουν κάποια πρόσθετα χαρακτηριστικά. Τοπικό κράτος είναι μια δυνατότητα που διατίθεται μόνο σε τμήματα κλάσης.

setState είναι η μέθοδος API που παρέχεται με τη βιβλιοθήκη έτσι ώστε ο χρήστης να είναι σε θέση να καθορίσει και να χειριστεί την κατάσταση με την πάροδο του χρόνου.

Τρεις κανόνες του αντίχειρα κατά τη χρήση του setState ()

Μην τροποποιείτε άμεσα την κατάσταση

Οι ενημερώσεις κατάστασης ενδέχεται να είναι ασύγχρονες

Το React μπορεί να περιλαμβάνει πολλές setState()κλήσεις σε μία ενημέρωση για απόδοση.

Επειδή this.props και this.stateμπορεί να ενημερωθεί ασύγχρονα, δεν πρέπει να βασίζεστε στις τιμές τους για τον υπολογισμό της επόμενης κατάστασης.

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

Οι ενημερώσεις κατάστασης συγχωνεύονται

Όταν καλείτε setState(), το React συγχωνεύει το αντικείμενο που παρέχετε στο τρέχον state.

Στο παρακάτω παράδειγμα, ενημερώνουμε τη μεταβλητή dogNeedsVaccinationανεξάρτητα από τις άλλες stateμεταβλητές.

Η συγχώνευση είναι ρηχή, επομένως this.setState({ dogNeedsVaccination: true }) αφήνει ανέπαφες τις άλλες μεταβλητές, αντικαθιστώντας μόνο την τιμή του dogNeedsVaccination.

Σεβαστείτε τη ροή δεδομένων και αποφύγετε να δηλώσετε το Μέγιστο

Τα δεδομένα ρέουν κάτω! Κανένα στοιχείο γονέα ή παιδιού δεν μπορεί να γνωρίζει εάν ένα συγκεκριμένο στοιχείο είναι κατάσταση ή ανιθαγενές και δεν πρέπει να νοιάζεται αν ορίζεται ως συνάρτηση ή τάξη.

Γι ' stateαυτό συχνά ονομάζεται τοπικό ή ενθυλακωμένο. Δεν είναι προσβάσιμο σε κανένα άλλο στοιχείο εκτός από αυτό που το κατέχει και το θέτει.

Όταν χρησιμοποιείτε setStateένα στήριγμα και το χρησιμοποιείτε στο στοιχείο σας, σπάτε τη ροή των στηριγμάτων απόδοσης. Εάν για κάποιο λόγο το στήριγμα που μεταβιβάστηκε στο στοιχείο σας άλλαξε στο γονικό στοιχείο, το παιδί δεν θα αποδώσει ξανά αυτόματα-μαγικά ;!

Ας δούμε ένα παράδειγμα:

Εδώ έχετε ένα HomeComponent που δημιουργεί έναν μαγικό αριθμό κάθε 1000ms και το θέτει σε δικό του state.

Μετά από αυτό αποδίδει τον αριθμό και επικαλείται τρία Childσυστατικά (αδέλφια) που θα λάβουν τον μαγικό αριθμό με στόχο την εμφάνισή του χρησιμοποιώντας τρεις διαφορετικές προσεγγίσεις:

Πρώτη προσέγγιση

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

Δεύτερη προσέγγιση

Το στοιχείο ChildOfHomeBrotherλαμβάνει το propsαπό τον γονέα του και, επικαλούμενος componentDidMount, ορίζει τον μαγικό αριθμό σε state. Τότε αποδίδει το state.magicNumber.

Αυτό το παράδειγμα δεν λειτουργεί επειδή render()δεν γνωρίζει ότι το a prop έχει αλλάξει, ώστε να μην ενεργοποιεί την εκ νέου απόδοση του στοιχείου. Δεδομένου ότι το στοιχείο δεν αποδίδεται πλέον, componentDidMountδεν γίνεται επίκληση και η οθόνη δεν ενημερώνεται.

Τρίτη προσέγγιση

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

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

Αυτό είναι λάθος, εκτός εάν πρέπει να επιτρέψετε στον χρήστη να αλλάξει την τιμή στήριξης που λαμβάνεται.

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

Μπορείτε να ελέγξετε μια ιστοσελίδα που λειτουργεί με αυτό το παράδειγμα που έχω προετοιμάσει για εσάς στο Glitch. Ρίξτε μια ματιά και διασκεδάστε;

Επίσης, ρίξτε μια ματιά στον κώδικα στο ( Home.jsκαι HomeCodeCleaned.jsχωρίς το HTML) στο repo μου σχετικά με αυτό το άρθρο.

Πώς να ρυθμίσετε τοState

Έτσι σε αυτό το σημείο νομίζω ότι είναι καιρός να βρώσουμε τα χέρια μας βρώμικα!

Ας παίξουμε λίγο setStateκαι βελτιώστε το! Απλά ακολουθήστε και πιάστε ένα άλλο φλιτζάνι καφέ!

Ας δημιουργήσουμε μια μικρή φόρμα για την ενημέρωση των δεδομένων χρήστη:

Ακολουθεί ο κωδικός για το παραπάνω παράδειγμα:

Ρυθμίζουμε stateως αντικείμενο και δεν υπάρχει πρόβλημα επειδή η τρέχουσα κατάστασή μας δεν εξαρτάται από την τελευταία μας κατάσταση.

Τι γίνεται αν δημιουργήσουμε ένα ακόμη πεδίο φόρμας για να εισαγάγουμε και να εμφανίσουμε το επώνυμο;

Ομορφη! Έχουμε αφαιρέσει τη handleFormChangeμέθοδο για να μπορούμε να χειριστούμε όλα τα πεδία εισαγωγής και setState.

Τι γίνεται αν προσθέσουμε ένα κουμπί εναλλαγής για να επισημάνουμε τα δεδομένα ως έγκυρα ή μη έγκυρα και έναν μετρητή για να μάθουμε πόσες αλλαγές έχουμε κάνει στην πολιτεία;

Ναι! Λικνίζουμε! Έχουμε αφαιρέσει πολλά πράγματα!

Χμμμ… Ας πούμε ότι δεν θέλω ένα πλαίσιο ελέγχου να ελέγχει τη isValidμεταβλητή αλλά ένα απλό κουμπί εναλλαγής.

Ας διαχωρίσουμε επίσης τον χειριστή μετρητών από αυτήν τη μέθοδο. Λειτουργεί καλά, αλλά σε πιο περίπλοκες καταστάσεις όπου το React πρέπει να αλλάξει παρτίδες / ομάδες, δεν είναι καλή πολιτική να βασίζεστε στη this.state.counterμεταβλητή για να προσθέσετε μία ακόμη. Αυτή η τιμή μπορεί να αλλάξει χωρίς να το γνωρίζετε.

Χρησιμοποιούμε ένα ρηχό αντίγραφο του τη στιγμή που καλείται η λειτουργία και σε αυτό το συγκεκριμένο χρονικό σημείο δεν ξέρετε αν η αξία του είναι αυτή που περιμένατε ή όχι!

Ας πάμε λίγο λειτουργικά!

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

Έτσι, αυτή τη στιγμή συνεχίζουμε να handleFormChangeμεταδίδουμε ένα αντικείμενο στη setStateμέθοδο API. Αλλά οι μέθοδοι handleCounterκαι οι handleIsValidμέθοδοι είναι τώρα λειτουργικές και ξεκινούν αρπάζοντας την τρέχουσα κατάσταση και μετά, ανάλογα με αυτήν την κατάσταση, αλλάζοντάς την στην επόμενη.

Αυτός είναι ο σωστός τρόπος αλλαγής stateτων μεταβλητών που εξαρτώνται από την προηγούμενη κατάσταση.

Τι γίνεται αν θέλουμε να console.log()δηλώσουμε τις αλλαγές firstNameκαι lastNameτις φόρμες εισαγωγής κάθε φορά που πραγματοποιείται μια αλλαγή; Ας το δοκιμάσουμε!

Ομορφη! Κάθε φορά που handleFormChangeσυμβαίνει (που σημαίνει ότι συνέβη ένα νέο πάτημα πλήκτρου) η logFields()μέθοδος καλείται και καταγράφει την τρέχουσα κατάσταση στην κονσόλα!

Ας δούμε την κονσόλα του προγράμματος περιήγησης:

Περίμενε! Τι συνέβη εδώ; Το αρχείο καταγραφής της κονσόλας είναι μία αλλαγή πριν από την τρέχουσα εισαγωγή φόρμας! Γιατί συμβαίνει αυτό?

Το setState είναι ασύγχρονο !!

Το γνωρίζαμε ήδη, αλλά τώρα το βλέπουμε με τα μάτια μας! Τι συμβαίνει εκεί; Ας ρίξουμε μια ματιά στις παραπάνω μεθόδους handleFormChangeκαι logFields.

Έτσι, η handleFormChangeμέθοδος λαμβάνει το όνομα και την τιμή του συμβάντος και στη συνέχεια λαμβάνει ένα setStateαπό αυτά τα δεδομένα. Στη συνέχεια καλεί το handleCounterγια να ενημερώσει τις πληροφορίες μετρητή και στο τέλος επικαλείται τη logFieldsμέθοδο. Η logFieldsμέθοδος αρπάζει το currentStateκαι επιστρέφει το «Eduard» αντί του «Eduardo».

Το θέμα είναι: setStateείναι ασύγχρονο και δεν ενεργεί αυτή τη στιγμή. Το React κάνει τη δουλειά του και εκτελεί logFieldsπρώτα τη μέθοδο, αφήνοντας setStateτον επόμενο βρόχο συμβάντος.

Αλλά πώς μπορούμε να αποφύγουμε τέτοιου είδους καταστάσεις;

Λοιπόν, το setStateAPI πρέπει callbackνα αποφύγει αυτήν την κατάσταση:

Εάν θέλουμε logFields()να λάβουμε υπόψη τις πρόσφατες αλλαγές που κάναμε στην πολιτεία, πρέπει να την επικαλεστεί μέσα στην επιστροφή κλήσης, ως εξής:

Εντάξει, τώρα λειτουργεί!

Λέμε στο React: «Hey React! Προσέξτε ότι όταν επικαλέστε τη logFieldsμέθοδο, θέλω να έχετε την stateήδη ενημερωμένη εντάξει; Σε εμπιστεύομαι!"

Ο React λέει: «Εντάξει Έντο! Θα χειριστώ όλα αυτά τα πράγματα που συνήθως κάνω στην πίσω αυλή με το setStateπράγμα και μόνο όταν τελειώσω με αυτό θα επικαλεστώ logFields()! Ψύχραιμος, χαλαρός! Χαλαρώστε!"

Και στην πραγματικότητα - λειτούργησε!

Εντάξει όλοι! Μέχρι τώρα έχουμε χειριστεί τις μεγάλες παγίδες του setState.

Έχετε το θάρρος να προχωρήσετε πέρα ​​από τον τοίχο; Πιάσε ένα φλιτζάνι καφέ και ας πάμε πραγματικά ...

Γίνετε φανταχτερός με το setState ()

Τώρα που έχουμε handleCounterκαι handleIsValidμεθόδους, και setState()εκφράζονται με συναρτήσεις, μπορούμε να συνθέσουμε την ενημέρωση κατάστασης με άλλες συναρτήσεις! Μου αρέσει η σύνθεση! Ας διασκεδάσουμε!

Μπορούμε να πάρουμε τη λογική μέσα setStateσε μια συνάρτηση έξω από το στοιχείο κλάσης. Ας το ονομάσουμε toggleIsValid. ☝️

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

Τι γίνεται αν χρησιμοποιούμε μια λειτουργία υψηλότερης παραγγελίας;

Ουάου! Τώρα δεν επικαλούμε τη toggleIsValidλειτουργία. Ζητούμε μια αφηρημένη συνάρτηση υψηλότερης τάξης που ονομάζεται toggleKeyκαι μεταδίδουμε ένα κλειδί (συμβολοσειρά σε αυτήν την περίπτωση) σε αυτήν.

Πώς πρέπει να αλλάξουμε τη toggleIsValidλειτουργία τώρα;

Τι?! Τώρα έχουμε μια συνάρτηση που ονομάζεται toggleKeyπου λαμβάνει keyκαι επιστρέφει μια νέα συνάρτηση που αλλάζει κατάσταση σύμφωνα με το παρεχόμενο κλειδί.

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

Μεγάλος!

Ας κάνουμε το ίδιο με τον χειριστή αύξησης:

Ναι! Δουλεύει! Τόσο ωραία. Ας τρελαθούμε τώρα…

Γυρίσματα της Σελήνης και επιστροφή

Τι γίνεται αν δημιουργήσουμε μια γενική makeUpdaterσυνάρτηση που λαμβάνει τη συνάρτηση μετασχηματισμού που θέλετε να εφαρμόσετε, παίρνει το κλειδί και επιστρέφει τη συνάρτηση κατάστασης που διαχειρίζεται την κατάσταση με τη συνάρτηση μετασχηματισμού και το κλειδί; Λίγο μπερδεμένος; Πάμε!

Εντάξει, αυτό είναι αρκετό… Ας σταματήσουμε εδώ. ;

Μπορείτε να ελέγξετε όλο τον κώδικα που έχουμε κάνει σε αυτό το repo GitHub.

Τελευταίο αλλά εξίσου σημαντικό

Μην ξεχάσετε να αποφύγετε τη μέγιστη κατάσταση χρήσης και να σεβαστείτε τον καταρράκτη React rendering props.

Μην ξεχνάτε setStateείναι ασύγχρονος.

Μην ξεχνάτε ότι setStateμπορεί να πάρει ένα αντικείμενο ή μια συνάρτηση

Μην ξεχνάτε ότι πρέπει να περάσετε μια συνάρτηση όταν η επόμενη κατάστασή σας εξαρτάται από την προηγούμενη κατάστασή σας.

Βιβλιογραφία

  1. Αντιδράστε την τεκμηρίωση
  2. Προσεγγίστε τεχνικά μαθήματα από τον Ryan Florence, το οποίο προτείνω πραγματικά.

Ευχαριστώ πολύ!