Πώς να δημιουργήσετε μια λίστα Todo με React Hooks

Το React v16.7.0-alpha παρουσίασε τους Hooks και είμαι ενθουσιασμένος.

Τι είναι οι γάντζοι;

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

Μερικά οφέλη είναι

  • Απομόνωση της κρατικής λογικής, διευκολύνοντας τον έλεγχο.
  • Κοινή χρήση λογικής λογικής χωρίς στοιχεία απόδοσης ή στοιχεία υψηλότερης τάξης.
  • Διαχωρίζοντας τις ανησυχίες της εφαρμογής σας με βάση τη λογική και όχι τα άγκιστρα του κύκλου ζωής.
  • Αποφεύγοντας τάξεις ES6, επειδή είναι ιδιότροπες, όχι στην πραγματικότητα τάξεις και ανεβάζουν ακόμη και έμπειρους προγραμματιστές JavaScript.

Για περισσότερες λεπτομέρειες, δείτε την επίσημη εισαγωγή της React Hooks.

Υιοθετήστε σταδιακά τους γάντζους

Τη στιγμή της γραφής, οι Hooks ήταν άλφα και το API τους θα μπορούσε να είχε αλλάξει ανά πάσα στιγμή.

Το React 16.8.0 ήταν η πρώτη σταθερή κυκλοφορία που υποστηρίζει τα Hooks, και υπάρχουν περισσότερα σεμινάρια και παραδείγματα κώδικα κάθε μέρα. Ωστόσο, δεδομένου ότι δεν υπάρχουν σχέδια για την κατάργηση τάξεων από το React και τα Hooks θα λειτουργήσουν με τον υπάρχοντα κώδικα, η ομάδα του React συνιστά την αποφυγή "μεγάλων επανεγγραφών" Αντ 'αυτού, προτείνουν την εξάσκηση των γάντζων σε μη κρίσιμα συστατικά πρώτα και στη συνέχεια τη χρήση τους στη θέση των τάξεων προς τα εμπρός.

Ας φτιάξουμε μια λίστα Todo

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

Η δική μας θα κάνει μόνο μερικά πράγματα

  • Εμφάνιση των todos με ωραίο τρόπο σχεδίασης υλικών
  • Επιτρέψτε την προσθήκη todos μέσω εισόδου
  • Διαγραφή todos

Ρύθμιση

Ακολουθούν οι σύνδεσμοι GitHub και CodeSandbox.

git clone //github.com/yazeedb/react-hooks-todo cd react-hooks-todo npm install 

Το masterυποκατάστημα έχει ολοκληρώσει το έργο, οπότε ελέγξτε το startυποκατάστημα εάν θέλετε να ακολουθήσετε.

git checkout start

Και εκτελέστε το έργο.

npm start

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

Έχει ήδη ρυθμιστεί με material-ui για να δώσει στη σελίδα μας μια επαγγελματική εμφάνιση. Ας αρχίσουμε να προσθέτουμε κάποια λειτουργικότητα!

Το συστατικό TodoForm

Προσθέστε ένα νέο αρχείο, src/TodoForm.js. Εδώ είναι ο κωδικός εκκίνησης.

import React from 'react'; import TextField from '@material-ui/core/TextField'; const TodoForm = ({ saveTodo }) => { return (    ); }; export default TodoForm; 

Δεδομένου του ονόματος, γνωρίζουμε ότι η δουλειά του είναι να προσθέσει todos στην πολιτεία μας. Μιλώντας για αυτό, εδώ είναι το πρώτο μας γάντζο .

χρησιμοποιήστε το κράτος

Ελέγξτε αυτόν τον κωδικό

import { useState } from 'react'; const [value, setValue] = useState(''); 

useStateείναι απλώς μια συνάρτηση που παίρνει την αρχική κατάσταση και επιστρέφει έναν πίνακα. Προχωρήστε και console.logαυτό.

Το πρώτο ευρετήριο του πίνακα είναι η τρέχουσα τιμή της κατάστασής σας και το δεύτερο ευρετήριο είναι μια συνάρτηση ενημέρωσης.

Έτσι τα ονομάσαμε καταλλήλως valueκαι setValueχρησιμοποιώντας την εκκαθάριση ES6.

useState with Forms

Η φόρμα μας πρέπει να παρακολουθεί την αξία της εισαγωγής και να καλεί saveTodoκατά την υποβολή. useStateμπορεί να μας βοηθήσει με αυτό!

Ενημέρωση TodoForm.js, ο νέος κωδικός είναι με έντονους χαρακτήρες .

import React, { useState } from 'react'; import TextField from '@material-ui/core/TextField'; const TodoForm = ({ saveTodo }) => { const [value, setValue] = useState(''); return (  { event.preventDefault(); saveTodo(value); }} >  { setValue(event.target.value); }} value={value} />  ); }; export default TodoForm; 

Επιστρέψτε index.js, εισαγάγετε και χρησιμοποιήστε αυτό το στοιχείο.

// ... import TodoForm from './TodoForm'; // ... const App = () => { return ( Todos ); }; 

Τώρα η τιμή σας είναι συνδεδεμένη στην υποβολή (πατήστε enter).

χρησιμοποιήστεState With Todos

Χρειαζόμαστε επίσης κατάσταση για τα todos μας. Εισαγωγή useStateσε index.js. Η αρχική μας κατάσταση πρέπει να είναι ένας κενός πίνακας.

import React, { useState } from 'react'; // ... const App = () => { const [todos, setTodos] = useState([]); // ... }; 

Συστατικό TodoList

Δημιουργήστε ένα νέο αρχείο που ονομάζεται src/TodoList.js.

Επεξεργασία: Ευχαριστώ Takahiro Hata που με βοήθησες να μετακομίσω onClickστο σωστό σημείο!

import React from 'react'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import Checkbox from '@material-ui/core/Checkbox'; import IconButton from '@material-ui/core/IconButton'; import DeleteIcon from '@material-ui/icons/Delete'; const TodoList = ({ todos, deleteTodo }) => (  {todos.map((todo, index) => (      { deleteTodo(index); }} >     ))}  ); export default TodoList; 

Χρειάζονται δύο στηρίγματα

  • todos: Ο πίνακας των todos. Έχουμε mapπάνω από κάθε μία και να δημιουργήσετε ένα στοιχείο λίστας.
  • deleteTodo: Clicking a todo’s IconButton fires this function. It passes the index, which will uniquely identify a todo in our list.

Import this component in your index.js.

import TodoList from './TodoList'; import './styles.css'; const App = () => { //... }; 

And use it in your App function like so

Adding Todos

Still in index.js, let’s edit our TodoForm’s prop, saveTodo.

 { const trimmedText = todoText.trim(); if (trimmedText.length > 0) { setTodos([...todos, trimmedText]); } }} />

Simply merge the existing todos with our new one, extra whitespace cut out.

We can add todos now!

Clearing the Input

Notice the input isn’t clearing after adding a new todo. That’s a bad user experience!

We can fix it with a small code change in TodoForm.js.

 { event.preventDefault(); saveTodo(value); setValue(''); }} />

Once a todo’s saved, set the form state to an empty string.

It’s looking good now!

Deleting Todos

TodoList provides each todo’s index, as it’s a guaranteed way to find the one we want to delete.

TodoList.js

 { deleteTodo(index); }} >

Θα το εκμεταλλευτούμε αυτό μέσα index.js.

 { const newTodos = todos.filter((_, index) => index !== todoIndex); setTodos(newTodos); }} />

Ό, τι todos δεν ταιριάζει με τα παρεχόμενα indexδιατηρούνται και αποθηκεύονται σε κατάσταση χρήσης setTodos.

Η λειτουργία διαγραφής ολοκληρώθηκε!

Περίληψη της χρήσης του Τότου

Ανέφερα ότι τα άγκιστρα είναι ιδανικά για το διαχωρισμό της λογικής της κατάστασης και των στοιχείων. Δείτε πώς φαίνεται στην εφαρμογή todo.

Δημιουργήστε ένα νέο αρχείο που ονομάζεται src/useTodoState.js.

import { useState } from 'react'; export default (initialValue) => { const [todos, setTodos] = useState(initialValue); return { todos, addTodo: (todoText) => { setTodos([...todos, todoText]); }, deleteTodo: (todoIndex) => { const newTodos = todos.filter((_, index) => index !== todoIndex); setTodos(newTodos); } }; }; 

Είναι ο ίδιος κωδικός μας index.js, αλλά χωρισμένος! Η κρατική μας διαχείριση δεν συνδέεται πλέον στενά με το στοιχείο.

Τώρα απλώς εισαγάγετε το.

import React from 'react'; import ReactDOM from 'react-dom'; import Typography from '@material-ui/core/Typography'; import TodoForm from './TodoForm'; import TodoList from './TodoList'; import useTodoState from './useTodoState'; import './styles.css'; const App = () => { const { todos, addTodo, deleteTodo } = useTodoState([]); return ( Todos   { const trimmedText = todoText.trim(); if (trimmedText.length > 0) { addTodo(trimmedText); } }} /> ); }; const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement); 

Και όλα λειτουργούν ακόμα κανονικά.

Περίληψη Φόρμας Εισαγωγή χρήσηςState

Μπορούμε να κάνουμε το ίδιο με τη φόρμα μας!

Δημιουργήστε ένα νέο αρχείο, src/useInputState.js.

import { useState } from 'react'; export default (initialValue) => { const [value, setValue] = useState(initialValue); return { value, onChange: (event) => { setValue(event.target.value); }, reset: () => setValue('') }; }; 

Και τώρα TodoForm.jsπρέπει να μοιάζει με αυτό.

import React from 'react'; import TextField from '@material-ui/core/TextField'; import useInputState from './useInputState'; const TodoForm = ({ saveTodo }) => { const { value, reset, onChange } = useInputState(''); return (  { event.preventDefault(); saveTodo(value); reset(); }} >   ); }; export default TodoForm; 

Και τελειώσαμε όλοι! Ελπίζω να σας άρεσε, μέχρι την επόμενη φορά!