Προσθήκη reducer στην εφαρμογή Redux

Στο προηγούμενο μάθημα δημιουργήσαμε το component UserReaction έτσι ώστε κάθε προϊόν να έχει και αντιδράσεις χρηστών. Τώρα πρέπει να γράψουμε ένα reducer, που θα χειρίζεται τον μετρητή αντιδράσεων όταν ο χρήστης κλικάρει πάνω στο κουμπί της μίας ή της άλλης αντίδρασης.

Ας ανοίξουμε την εφαρμογή μας με τα προϊόντα, και σε αυτή το αρχείο productsSlice.js με όλους τους reducers. Τώρα στην ιδιότητα reducers θα δημιουργήσουμε έναν ακόμη reducer reactionClicked (μπορούμε να τον βάλουμε πρώτο - πριν από τον productAdded, αν και δεν έχει σημασία). Όπως συνήθως, θα του περάσουμε ως παραμέτρους state και action:

products/productsSlice.jsreactionClicked(state, action) {},

Και τώρα μέσα στις αγκύλες, που αφήσαμε κενές στο προηγούμενο βήμα, θα γράψουμε τον κώδικά του. Πρώτα απ' όλα θα εξαγάγουμε το id του προϊόντος από το payload του αντικειμένου action και το όνομα της αντίδρασης:

products/productsSlice.jsconst { productId, reaction } = action.payload

Έπειτα από το state που περάστηκε θα πάρουμε το αντίστοιχο προϊόν:

products/productsSlice.jsconst currentProduct = state.find(product => product.id === productId)

Και αν υπάρχει τέτοιο προϊόν, τότε θα αυξήσουμε την τιμή της αντίδρασης που περάστηκε κατά 1:

products/productsSlice.jsif (currentProduct) {
  currentProduct.reactions[reaction]++
}

Αυτό ήταν, ο κώδικάς μας για τον reactionClicked είναι έτοιμος:

products/productsSlice.jsreactionClicked(state, action) {
  const { productId, reaction } = action.payload
  const currentProduct = state.find(product => product.id === productId)
  if (currentProduct) {
    currentProduct.reactions[reaction]++
  }
},

Ας προσθέσουμε στο τέλος του αρχείου την εξαγωγή του δημιουργηθείντος action creator:

products/productsSlice.jsxexport const {
  reactionClicked,
  productAdded,
  productUpdated
} = productsSlice.actions

Εδώ είναι απαραίτητο να σημειώσουμε δύο σημαντικά σημεία. Όπως θυμάστε από τα προηγούμενα μαθήματα - δεν επιτρέπεται να ενημερώνετε έτσι απευθείας την τιμή στον κώδικα του reducer (κοιτάξτε αυτή τη γραμμή: reactions[reaction]++), αλλά εδώ μας βολεύει, γιατί το κάνουμε μέσα στο createSlice, που χρησιμοποιεί τη βιβλιοθήκη Immer. Αυτή θα φροντίσει να μετατρέψει τον κώδικά μας σε "ασφαλή" ενημέρωση τιμής. Αυτό μας επιτρέπει να γράφουμε πολύπλοκα πράγματα με πιο απλό τρόπο.

Το επόμενο, που πρέπει να θυμάστε - το αντικείμενο action πρέπει να περιέχει την ελάχιστη δυνατή ποσότητα πληροφορίας - μόνο για να υποδείξει τι συνέβη. Δεν αξίζει να κάνετε σε αυτό υπολογισμούς. Όλους τους υπολογισμούς για την ενημέρωση του state πρέπει να τους κάνετε στο reducer, εδώ μπορείτε να γράψετε για αυτό όση λογική χρειαστεί.

Задание 1

Ανοίξτε την εφαρμογή σας με τους μαθητές και στο αρχείο studentsSlice.js προσθέστε έναν ακόμη reducer voteClicked στο πεδίο reducers, όπως φαίνεται στο μάθημα. Γράψτε κώδικα για αυτόν. Ο στόχος του reducer σας - όταν γίνεται κλικ να αυξάνει την τιμή του vote (ή της ψήφου), πάνω στην οποία έγινε κλικ, για τον συγκεκριμένο μαθητή, κατά 1.

Задание 2

Στο τέλος του αρχείου μην ξεχάσετε να εξάγετε τον δημιουργηθέν action creator voteClicked.