Πώς να ανανεώσετε με δύναμη ένα παιδικό συστατικό React: ο εύκολος τρόπος

Σημείωση: Από το React 16, componentWillReceiveProps()έχει καταργηθεί, πράγμα που σημαίνει ότι εάν χρησιμοποιείτε αυτήν την έκδοση ή υψηλότερη στο έργο σας, αυτό δεν είναι καλή συμβουλή για εσάς.

Στον κόσμο των Αντιδράσεων, η επιβολή μιας εκ νέου απόδοσης παραβλέπεται. Πρέπει να αφήσετε το DOM να φροντίσει τον εαυτό του όταν το React αντιλαμβάνεται αλλαγές σε stateή props. Για να ακολουθήσουμε αυτά τα μοτίβα, μερικές φορές πρέπει να κάνουμε πράγματα που φαίνονται λίγο ανόητα. Εξετάστε αυτό το σενάριο:

Έχουμε δύο συστατικά - έναν γονέα και ένα παιδί. Ο γονέας πραγματοποιεί μια κλήση API για τη λήψη του user. Από αυτό, παίρνουμε τα πράγματα όπως name, age, favorite color. Παίρνουμε επίσης idαπό τη βάση δεδομένων μας. Θα το μεταβιβάσουμε στο θυγατρικό μας στοιχείο, το οποίο πρόκειται επίσης να πραγματοποιήσει μια κλήση API, με το αναγνωριστικό χρήστη. Καταπληκτικά - πολλά δεδομένα εισέρχονται στην εφαρμογή μας.

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

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

Αντιδράστε τα βασικά στοιχεία απόδοσης

Το μικρό είναι ότι το React θα ενημερώσει μόνο τμήματα του DOM που έχουν αλλάξει. Σε αυτήν την περίπτωση, το propsπέρασμα στο στοιχείο παπουτσιού ( userId) δεν έχει αλλάξει, οπότε τίποτα δεν αλλάζει στο παιδικό μας στοιχείο.

Η προτίμηση χρώματος για τον χρήστη θα ενημερωθεί όταν λάβουμε νέες πληροφορίες από το API - υποθέτοντας ότι κάνουμε κάτι με την απόκριση μετά την ενημέρωση ενός χρήστη.

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

Ο αρχικός κωδικός

const UserShow extends Component { state = { user: {} } componentDidMount() { this.fetchUser().then(this.refreshUser) } setNewColor = color => { this.updateUser({color}).then(this.refreshUser) } refreshUser = res => this.setState({user: res.data.user}) render() { const { user } = this.state; return ( User name: {user.name} Pick color: {colors.map(color => this.setNewColor(color)} />)} )} ) } }

Θα ShoeListείναι απλώς μια λίστα με παπούτσια, τα οποία θα πάρουμε από τον διακομιστή με το αναγνωριστικό χρήστη:

const ShoeList extends Component { state = { shoes: [] } componentDidMount() { this.fetchShoes(this.props.id) .then(this.refreshShoeList) } refreshShoeList = res => this.setState({ shoes: res.data.shoes }) render() { // some list of shoes } }

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

Στην πραγματικότητα, με τον τρόπο που γράφεται, ShoeListδεν θα ανανεωθεί ποτέ, καθώς δεν εξαρτώνται από στηρίγματα για απόδοση. Ας το διορθώσουμε.

Ενεργοποίηση θυγατρικού στοιχείου για εκ νέου απόδοση

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

Για να γίνει αυτό, θα προσθέσουμε μια μέθοδο σε setNewColor:

[...] setNewColor = color => { this.updateUser({color}).then(res => { this.refreshUser(res); this.refreshShoeList(); }) } refreshShoeList = () => this.setState({refreshShoeList: !this.state.refreshShoeList}) [...] 
    

This is a simple switch we can flip. I’ve kept things as simple as possible, but in production we’d want to make sure that the color we’re setting is different than the color we had before. Otherwise, there will be nothing to update.

Now in the ShoeList:

componentWillReceiveProps(props) { const { refresh, id } = this.props; if (props.refresh !== refresh) { this.fetchShoes(id) .then(this.refreshShoeList) } }

If you pass only refreshShoeList and then toggle based on that boolean, the component will just update forever and ever and ever.

We need to make sure the switch has flipped only once — so we’ll just check that the props coming in are different than the props we had before. If they are different, we’ll make a new API call to get the new list of shoes.

And boom — our child component has been “forced” to update.

componentWillReceiveProps

It’s worth taking just one more minute to review what’s going on in that last piece of code. In componentWillReceiveProps we have our only opportunity to view new props as they are coming in and compare them with previous props.

Here we can detect changes (like in refresh) and we can also make checks for new props (note, for instance, that refresh is initially undefined).

This React method is a very powerful way to manipulate and examine props.