Kā izveidot Todo sarakstu ar React Hooks

React v16.7.0-alfa iepazīstināja ar Hooks, un es esmu sajūsmā.

Kas ir āķi?

Tās ir funkcijas, kas sniedz jums React funkcijas, piemēram, stāvokļa un dzīves cikla āķi bez ES6 klasēm.

Daži ieguvumi ir

  • Izolējot loģisko loģiku, padarot to vieglāk pārbaudāmu.
  • Dalīšanās ar loģisku loģiku bez renderēšanas rekvizītiem vai augstākas pakāpes komponentiem.
  • Atdaliet savas lietotnes problēmas, pamatojoties uz loģiku, nevis uz dzīves cikla āķiem.
  • Izvairīšanās no ES6 klasēm, jo ​​tās ir dīvainas, patiesībā nav klases, un pat pieredzējuši JavaScript izstrādātāji.

Lai iegūtu sīkāku informāciju, skatiet React oficiālo ievadu Hooks.

Pakāpeniski pieņemiet āķus

Raksta tapšanas laikā Hooks bija alfa, un viņu API varēja mainīt jebkurā laikā.

React 16.8.0 bija pirmais stabilais laidiens, kas atbalstīja Hooks, un katru dienu ir vairāk apmācību un koda paraugu. Tomēr, tā kā nav paredzēts noņemt klases no React un Hooks darbosies ar esošo kodu, React komanda iesaka izvairīties no "lieliem pārrakstījumiem". Tā vietā viņi iesaka vispirms praktizēt āķus nekritiskos komponentos, pēc tam tos izmantot nākamo stundu vietā.

Veidosim Todo sarakstu

Todo saraksti ir visizplatītākais piemērs laba iemesla dēļ - tā ir fantastiska prakse. Es to iesaku jebkurai valodai vai bibliotēkai, kuru vēlaties izmēģināt.

Mūsējie darīs tikai dažas lietas

  • Parādiet uzdevumus jaukā materiāla dizaina veidā
  • Atļaut pievienot uzdevumus, izmantojot ievadi
  • Dzēst todos

Uzstādīt

Šeit ir saites GitHub un CodeSandbox.

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

masterFiliāle ir gatavo projektu, lai kases startfiliāli, ja vēlaties sekot līdzi.

git checkout start

Un vadīt projektu.

npm start

Lietotnei vajadzētu darboties localhost:3000, un šeit ir mūsu sākotnējais lietotāja interfeiss.

Tas jau ir izveidots ar materiālu-ui, lai mūsu lapai piešķirtu profesionālu izskatu. Sāksim pievienot dažas funkcionalitātes!

TodoForm komponents

Pievienojiet jaunu failu src/TodoForm.js. Šeit ir sākuma kods.

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

Ņemot vērā nosaukumu, mēs zinām, ka tā uzdevums ir pievienot mūsu valstij uzdevumus. Runājot par to, šeit ir mūsu pirmais āķis .

useState

Pārbaudiet šo kodu

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

useStateir tikai funkcija, kas iegūst sākotnējo stāvokli un atgriež masīvu. Uz priekšu un console.logtā.

Masīva pirmais indekss ir jūsu štata pašreizējā vērtība, un otrais indekss ir atjauninātāja funkcija.

So we appropriately named them value and setValue using ES6 destructuring assignment.

useState with Forms

Our form should track the input’s value and call saveTodo upon submit. useState can help us with that!

Update TodoForm.js, the new code’s in bold.

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; 

Back in index.js, import and use this component.

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

Now your value’s logged on submit (press enter).

useState With Todos

We also need state for our todos. Import useState in index.js. Our initial state should be an empty array.

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

TodoList Component

Create a new file called src/TodoList.js.

Edit: Thank you Takahiro Hata for helping me move onClick to the correct spot!

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; 

It takes two props

  • todos: The array of todos. We map over each one and create a list item.
  • 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); }} >

Mēs to izmantosim iekšā index.js.

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

Neatkarīgi no piedāvātajiem uzdevumiem indextiek glabāti un glabāti stāvoklī, izmantojot setTodos.

Dzēšanas funkcionalitāte ir pabeigta!

Anotācija Todos useState

Es minēju, ka āķi ir lieliski piemēroti stāvokļa un komponentu loģikas atdalīšanai. Lūk, kā tas var izskatīties mūsu todo lietotnē.

Izveidojiet jaunu failu ar nosaukumu 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); } }; }; 

Tas ir mūsu kods no index.js, bet atdalīts! Mūsu valsts vadība vairs nav cieši saistīta ar komponentu.

Tagad vienkārši importējiet to.

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); 

Un viss joprojām darbojas kā parasti.

Veidlapas ievades abstraktēšana useState

Mēs varam darīt to pašu ar savu formu!

Izveidojiet jaunu failu 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('') }; }; 

Un tagad TodoForm.jsvajadzētu izskatīties šādi.

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; 

Un mēs visi esam pabeiguši! Ceru, ka jums patika, līdz nākamajai reizei!