Πώς να γίνετε επαγγελματίας με το 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
ένα στήριγμα και το χρησιμοποιείτε στο στοιχείο σας, σπάτε τη ροή των στηριγμάτων απόδοσης. Εάν για κάποιο λόγο το στήριγμα που μεταβιβάστηκε στο στοιχείο σας άλλαξε στο γονικό στοιχείο, το παιδί δεν θα αποδώσει ξανά αυτόματα-μαγικά ;!
Ας δούμε ένα παράδειγμα:

Εδώ έχετε ένα Home
Component που δημιουργεί έναν μαγικό αριθμό κάθε 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
τον επόμενο βρόχο συμβάντος.
Αλλά πώς μπορούμε να αποφύγουμε τέτοιου είδους καταστάσεις;
Λοιπόν, το setState
API πρέπει 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
μπορεί να πάρει ένα αντικείμενο ή μια συνάρτηση
Μην ξεχνάτε ότι πρέπει να περάσετε μια συνάρτηση όταν η επόμενη κατάστασή σας εξαρτάται από την προηγούμενη κατάστασή σας.
Βιβλιογραφία
- Αντιδράστε την τεκμηρίωση
- Προσεγγίστε τεχνικά μαθήματα από τον Ryan Florence, το οποίο προτείνω πραγματικά.
Ευχαριστώ πολύ!