Автор оригинала: FreeCodeCamp Community Member.
В этой статье вы построете приложение для управления книгами в реакции с нуля.
Создавая это приложение, вы узнаете:
- Как выполнить операции CRUD
- Как использовать React Router для навигации между маршрутами
- Как использовать API API React Context для передачи данных по маршрутам
- Как создать пользовательский крюк в реакции
- Как хранить данные в локальном хранилище, чтобы сохранить его даже после обновления страницы
- Как управлять данными, хранящимися в локальном хранилище, используя пользовательский крюк
и многое другое.
Мы будем использовать React Cloots для создания этого приложения. Так что если вы новичок, чтобы реагировать крюки, проверьте мой Введение в реактивный крюк Статья для изучения оснований.
Начальная настройка
Создайте новый проект, используя Create-React-App
:
npx create-react-app book-management-app
Как только проект создан, удалите все файлы из SRC
Папка и создать index.js
и styles.cscss
Файлы внутри SRC
папка. Также создать Компоненты
, контекст
, крючки
и Маршрутизатор
Папки внутри SRC
папка.
Установите необходимые зависимости:
yarn add bootstrap@4.6.0 lodash@4.17.21 react-bootstrap@1.5.2 node-sass@4.14.1 react-router-dom@5.2.0 uuid@8.3.2
Открыть styles.cscss
и добавьте содержимое от здесь внутри него.
Как создать начальные страницы
Создать новый файл Header.js
внутри Компоненты
Папка со следующим содержанием:
import React from 'react'; import { NavLink } from 'react-router-dom'; const Header = () => { return (); }; export default Header; Book Management App
Books List Add Book
Здесь мы добавили две навигационные ссылки с помощью Navlink
Компонент React-Router-DOM
: Один, чтобы увидеть список всех книг, а другой, чтобы добавить новую книгу.
Мы используем Navlink
Вместо якоря о якоре ( ), поэтому страница не будет обновляться, когда пользователь нажимает на любую из ссылок.
Создайте новый файл под названием Bookslist.js
внутри Компоненты
Папка со следующим содержанием:
import React from 'react'; const BooksList = () => { returnList of books
; }; export default BooksList;
Создайте новый файл под названием Addbood.js
внутри Компоненты
Папка со следующим содержанием:
import React from 'react'; import BookForm from './BookForm'; const AddBook = () => { const handleOnSubmit = (book) => { console.log(book); }; return (); }; export default AddBook;
В этом файле мы отображаем Bookform
компонент (который мы еще создаем).
Для Bookform
Компонент, мы передаем Руководство
Метод, поэтому мы можем сделать некоторую обработку позже, как только мы отправим форму.
Теперь создайте новый файл Bookform.js
внутри Компоненты
Папка со следующим содержанием:
import React, { useState } from 'react'; import { Form, Button } from 'react-bootstrap'; import { v4 as uuidv4 } from 'uuid'; const BookForm = (props) => { const [book, setBook] = useState({ bookname: props.book ? props.book.bookname : '', author: props.book ? props.book.author : '', quantity: props.book ? props.book.quantity : '', price: props.book ? props.book.price : '', date: props.book ? props.book.date : '' }); const [errorMsg, setErrorMsg] = useState(''); const { bookname, author, price, quantity } = book; const handleOnSubmit = (event) => { event.preventDefault(); const values = [bookname, author, price, quantity]; let errorMsg = ''; const allFieldsFilled = values.every((field) => { const value = `${field}`.trim(); return value !== '' && value !== '0'; }); if (allFieldsFilled) { const book = { id: uuidv4(), bookname, author, price, quantity, date: new Date() }; props.handleOnSubmit(book); } else { errorMsg = 'Please fill out all the fields.'; } setErrorMsg(errorMsg); }; const handleInputChange = (event) => { const { name, value } = event.target; switch (name) { case 'quantity': if (value === '' || parseInt(value) === +value) { setBook((prevState) => ({ ...prevState, [name]: value })); } break; case 'price': if (value === '' || value.match(/^\d{1,}(\.\d{0,2})?$/)) { setBook((prevState) => ({ ...prevState, [name]: value })); } break; default: setBook((prevState) => ({ ...prevState, [name]: value })); } }; return ({errorMsg &&); }; export default BookForm;{errorMsg}
}Book Name Book Author Quantity Book Price
Давайте понять, что мы здесь делаем.
Первоначально мы определили состояние как объект, используя Уместите
Крюк для хранения всех введенных деталей, как это:
const [book, setBook] = useState({ bookname: props.book ? props.book.bookname : '', author: props.book ? props.book.author : '', quantity: props.book ? props.book.quantity : '', price: props.book ? props.book.price : '', date: props.book ? props.book.date : '' });
Как мы будем использовать то же самое Bookform
Компонент для добавления и редактирования книги, мы впервые проверяем, если книга
опоры передаются или не используют тройной оператор.
Если пропущено пропущено, мы устанавливаем его в пропущенное значение, в противном случае пустая строка ( ''
).
Затем мы добавили состояние для отображения сообщения об ошибке, и мы использовали синтаксис разрушительств ES6 для обозначения каждого из свойств внутри состояния, как это:
const [errorMsg, setErrorMsg] = useState(''); const { bookname, author, price, quantity } = book;
От Bookform
Компонент, мы возвращаем форму, где мы вводим имя книги, книга автор, количество и цену. Мы используем React-bootstrap Рамки для отображения формы в приятном формате.
Каждое поле ввода добавило Onchange
обработчик, который называет HandlinPutchange
метод.
Внутри HandlinPutchange
Способ, мы добавили оператор коммутатора для изменения значения состояния на основе какого поля ввода.
Когда мы напечатаем что-нибудь в Количество
поле ввода, event.target.name
будет Количество
Таким образом, первый коммутатор будет соответствовать. Внутри этого переключателя мы проверяем, если введенное значение является целым числом без десятичной точки.
Если да, то только мы обновляем состояние, как показано ниже:
if (value === '' || parseInt(value) === +value) { setBook((prevState) => ({ ...prevState, [name]: value })); }
Таким образом, пользователь не может ввести какое-либо десятичное значение для поля ввода количества.
Для Цена
Чехол переключателя мы проверяем десятичное число только с двумя цифрами после десятичной точки. Итак, мы добавили регулярное проверку выражения, которое выглядит так: value.match (/^ \ d {1,} (\. \ d {0,2})? $/)
Отказ
Если цена стоимость соответствует регулярным выражению, только тогда мы обновляем состояние.
Примечание: Для обоих Количество
и Цена
Чехлы переключателя, мы также проверяем для пустых значений, как это: ценность
Отказ Это должно позволить пользователю полностью удалить введенное значение, если им нужно.
Без этого чека пользователь не сможет удалить введенное значение, нажав Ctrl + A + Удалить
Отказ
Для всех других входных полей необходимо выполнить корпус коммутатора по умолчанию, который будет обновлять состояние на основе введенного значения пользователя.
Далее, как только мы отправим форму, Руководство
Метод будет вызван.
Внутри этого метода мы впервые проверяем, ввел ли пользователь все детали, используя каждый
Метод массива:
const allFieldsFilled = values.every((field) => { const value = `${field}`.trim(); return value !== '' && value !== '0'; });
каждый
Метод Array является одним из наиболее полезных методов массива в JavaScript.
Если все значения заполнены, то мы создаем объект со всеми заполненными значениями. Мы также называем Руководство
Метод, передавая книгу как аргумент, в противном случае мы устанавливаем сообщение об ошибке.
Руководство
Способ передается как опоры от Доклад
составная часть.
if (allFieldsFilled) { const book = { id: uuidv4(), bookname, author, price, quantity, date: new Date() }; props.handleOnSubmit(book); } else { errorMsg = 'Please fill out all the fields.'; }
Обратите внимание, что создать уникальный идентификатор, мы называем uuidv4 ()
Метод от UUID пакет NPM.
Теперь создайте новый файл Arenter.js
внутри Маршрутизатор
Папка со следующим содержанием:
import React from 'react'; import { BrowserRouter, Switch, Route } from 'react-router-dom'; import Header from '../components/Header'; import AddBook from '../components/AddBook'; import BooksList from '../components/BooksList'; const AppRouter = () => { return (); }; export default AppRouter;
Здесь мы настроили маршрутизацию для различных компонентов, таких как Книжный список
и Доклад
используя React-Router-DOM
библиотека.
Теперь откройте SRC/index.js
Файл и добавьте следующее содержимое внутри него:
import React from 'react'; import ReactDOM from 'react-dom'; import AppRouter from './router/AppRouter'; import 'bootstrap/dist/css/bootstrap.min.css'; import './styles.scss'; ReactDOM.render(, document.getElementById('root'));
Теперь запустите приложение React, запустив следующую команду из терминала:
yarn start
Вы увидите следующий экран при доступе к приложению в http://localhost: 3000/ Отказ
Как видите, мы правильно сможем добавить книгу и отобразить ее на консоли.
Но вместо входа в консоль, давайте добавим его в локальное хранилище.
Как создать пользовательский крючок для локального хранения
Местное хранилище удивительно. Это позволяет легко хранить данные приложений в браузере и является альтернативой файлам файлов для хранения данных.
Преимущество использования локального хранилища состоит в том, что данные будут сохранены постоянно в кэше браузера, пока мы не удалим его, чтобы мы могли получить доступ к нему даже после обновления страницы. Как вы можете знать, данные, хранящиеся в состоянии реагирования, будут потеряны, как только мы обновим страницу.
Есть много случаев использования для локального хранилища, и один из них должен хранить товары корзины, поэтому они не будут удалены, даже если мы обновляем страницу.
Чтобы добавить данные в локальное хранилище, мы используем setiTem
Метод, предоставляя ключ и значение:
localStorage.setItem(key, value)
Чтобы узнать о местном хранении и различных приложениях подробно, проверить Эта статья Отказ
Создать новый файл uselocalstorage.js
внутри крючки
Папка со следующим содержанием:
import { useState, useEffect } from 'react'; const useLocalStorage = (key, initialValue) => { const [value, setValue] = useState(() => { try { const localValue = window.localStorage.getItem(key); return localValue ? JSON.parse(localValue) : initialValue; } catch (error) { return initialValue; } }); useEffect(() => { window.localStorage.setItem(key, JSON.stringify(value)); }, [key, value]); return [value, setValue]; }; export default useLocalStorage;
Здесь мы использовали USELOCALSTORAGE
крючок, который принимает ключ
и InitiveValue
Отказ
Для объявления государства, используя Уместите
Крюк, мы используем ленивая инициализация Отказ
Таким образом, код внутри функции передан Уместите
будет выполнен только один раз, даже если USELOCALSTORAGE
Крючок называется несколько раз на каждом повторном визуализации приложения.
Итак, изначально мы проверяем, есть ли какое-либо значение в локальном хранении с предоставленным ключ
И мы возвращаем стоимость, разбирая его с помощью Json.parse
Метод:
try { const localValue = window.localStorage.getItem(key); return localValue ? JSON.parse(localValue) : initialValue; } catch (error) { return initialValue; }
Потом позже, если есть какие-либо изменения в ключ
или ценность
, мы обновим локальное хранилище:
useEffect(() => { window.localStorage.setItem(key, JSON.stringify(value)); }, [key, value]); return [value, setValue];
Тогда мы возвращаем ценность
хранится в местном хранении и SetValue
Функция, которую мы позвоним, чтобы обновить данные локальной таблички.
Как использовать локальный крюк для хранения
Теперь давайте будем использовать это USELOCALSTORAGE
Крюк, чтобы мы могли добавить или удалить данные из локального хранения.
Открыть Arenter.js
Файл и используйте USELOCALSTORAGE
Крюк внутри компонента:
import useLocalStorage from '../hooks/useLocalStorage'; const AppRouter = () => { const [books, setBooks] = useLocalStorage('books', []); return ( ... ) }
Теперь нам нужно пройти Книги
и Устройства
как реквизит к Доклад
Компонент, поэтому мы можем добавить книгу в локальное хранилище.
Так что измените маршрут из этого кода:
к следующему коду:
( )} path="/add" />
Здесь мы используем рисунок рендеринга реквизита, чтобы пройти реквизиты по умолчанию, передаваемое React Router, наряду с Книги
и Устройства
Отказ
Ваш весь Arenter.js
файл будет выглядеть так сейчас:
import React from 'react'; import { BrowserRouter, Switch, Route } from 'react-router-dom'; import Header from '../components/Header'; import AddBook from '../components/AddBook'; import BooksList from '../components/BooksList'; import useLocalStorage from '../hooks/useLocalStorage'; const AppRouter = () => { const [books, setBooks] = useLocalStorage('books', []); return (); }; export default AppRouter; ( )} path="/add" />
Теперь открыть Addbood.js
и заменить его содержание следующим кодом:
import React from 'react'; import BookForm from './BookForm'; const AddBook = ({ history, books, setBooks }) => { const handleOnSubmit = (book) => { setBooks([book, ...books]); history.push('/'); }; return (); }; export default AddBook;
Во-первых, мы используем синтаксис разрезания ES6 для доступа к История
, Книги
и Устройства
реквизит в компонент.
История
PROP автоматически проходит через React Router на каждый компонент, упомянутый в <Маршрут/>
Отказ Мы проезжаем Книги
и Устройства
реквизит от Arenter.js
файл.
Мы храним все добавленные книги в массиве. Внутри Руководство
Метод, мы называем Устройства
Функция, передавая массив, добавив вновь добавленную книгу сначала, а затем распространение всех книг, уже добавленных в Книги
Массив, как показано ниже:
setBooks([book, ...books]);
Здесь я добавляю вновь добавленные книга
сначала, а затем распространять уже добавленные Книги
Потому что я хочу, чтобы последняя книга была отображена сначала, когда мы показываем список книг позже.
Но вы можете изменить заказ, если хотите так:
setBooks([...books, book]);
Это добавит недавно добавленную книгу в конце всех уже добавленных книг.
Мы можем использовать оператор по распространению, потому что мы знаем, что Книги
это массив (поскольку мы инициализировали его к пустую массиву []
в artiver.js
Файл, как показано ниже):
const [books, setBooks] = useLocalStorage('books', []);
Затем, как только книга добавлена в локальное хранилище, позвонив Устройства
Метод, внутри Руководство
Метод мы перенаправляем пользователя к Список книг
Страница используя история Метод:
history.push('/');
Теперь давайте проверим, можем ли мы сохранить книги для локального хранения или нет.
Как видите, книга правильно добавляется в локальное хранилище (и вы можете подтвердить это на вкладке «Приложения» инструментов Chrome DEV).
Как отображать добавленные книги на пользовательском интерфейсе
Теперь давайте покажем добавленные книги на интерфейсе UI под Список книг
меню.
Открыть Arenter.js
и пройти Книги
и Устройства
как реквизит к Книжный список
составная часть.
Ваш Arenter.js
файл будет выглядеть так сейчас:
import React from 'react'; import { BrowserRouter, Switch, Route } from 'react-router-dom'; import Header from '../components/Header'; import AddBook from '../components/AddBook'; import BooksList from '../components/BooksList'; import useLocalStorage from '../hooks/useLocalStorage'; const AppRouter = () => { const [books, setBooks] = useLocalStorage('books', []); return (); }; export default AppRouter; ( )} path="/" exact={true} /> ( )} path="/add" />
Здесь мы только что изменили первый маршрут, связанный с Книжный список
составная часть.
Теперь создайте новый файл Book.js
внутри Компоненты
Папка со следующим содержанием:
import React from 'react'; import { Button, Card } from 'react-bootstrap'; const Book = ({ id, bookname, author, price, quantity, date, handleRemoveBook }) => { return (); }; export default Book; {bookname} {' '}Author: {author}Quantity: {quantity}Price: {price}Date: {new Date(date).toDateString()}
Теперь откройте Bookslist.js
Файл и заменить его содержимое в следующий код:
import React from 'react'; import _ from 'lodash'; import Book from './Book'; const BooksList = ({ books, setBooks }) => { const handleRemoveBook = (id) => { setBooks(books.filter((book) => book.id !== id)); }; return (); }; export default BooksList; {!_.isEmpty(books) ? ( books.map((book) => ()) ) : ( No books available. Please add some books.
)}
В этом файле мы зацикливаемся над Книги
используя массив карта
метод и передача их как опоры Книга
составная часть.
Обратите внимание, что мы также передаем Handleremovebook
Функция как опоры, поэтому мы сможем удалить любую книгу, которую мы хотим.
Внутри Handleremovebook
Функция, мы называем Устройства
Функция, используя массив Фильтр
Способ сохранить только книги, которые не совпадают с предоставленной книгой ID
Отказ
const handleRemoveBook = (id) => { setBooks(books.filter((book) => book.id !== id)); };
Теперь, если вы проверяете приложение, посетив http://localhost: 3000/ Вы сможете увидеть добавленную книгу на UI.
Давайте добавим другую книгу, чтобы проверить весь поток.
Как видите, когда мы добавляем новую книгу, мы перенаправляем на страницу списка, где мы можем удалить книгу. Вы можете увидеть, что он мгновенно удаляется из пользовательского интерфейса, а также из локального хранилища.
Также, когда мы обновляем страницу, данные не теряются. Это сила местного хранения.
Как редактировать книгу
Теперь мы добавляем и удаляем функциональность для книг. Давайте добавим способ редактировать книги, которые у нас есть.
Открыть Book.js
и изменить код ниже:
{' '}
К настоящему коду:
{' '}
Здесь мы добавили OnClick
обработчик для перенаправления пользователя к /Редактировать/id_of_the_book
Маршрут, когда мы нажимаем на кнопку редактирования.
Но у нас нет доступа к История
объект в Книга
компонент, потому что История
Проп пропускается только к компонентам, которые упоминаются в <Маршрут/>
Отказ
Мы оказываем Книга
Компонент внутри Книжный список
компонент, чтобы мы могли получить доступ к История
только внутри Книжный список
составная часть. Тогда мы можем передать его как опоры Книга
составная часть.
Но вместо этого React Router обеспечивает простой способ, используя Эфистория
крюк.
Импорт Эфистория
крючок в верхней части Book.js
файл:
import { useHistory } from 'react-router-dom';
и внутри Книга
Компонент, позвоните в Эфистория
крюк.
const Book = ({ id, bookname, author, price, quantity, date, handleRemoveBook }) => { const history = useHistory(); ... }
Теперь у нас есть доступ к История
объект внутри Книга
составная часть.
Ваш весь Book.js
Файл выглядит так сейчас:
import React from 'react'; import { Button, Card } from 'react-bootstrap'; import { useHistory } from 'react-router-dom'; const Book = ({ id, bookname, author, price, quantity, date, handleRemoveBook }) => { const history = useHistory(); return (); }; export default Book; {bookname} {' '}Author: {author}Quantity: {quantity}Price: {price}Date: {new Date(date).toDateString()}
Создайте новый файл под названием EditBook.js
внутри Компоненты
Папка со следующим содержанием:
import React from 'react'; import BookForm from './BookForm'; import { useParams } from 'react-router-dom'; const EditBook = ({ history, books, setBooks }) => { const { id } = useParams(); const bookToEdit = books.find((book) => book.id === id); const handleOnSubmit = (book) => { const filteredBooks = books.filter((book) => book.id !== id); setBooks([book, ...filteredBooks]); history.push('/'); }; return (); }; export default EditBook;
Здесь для OnClick
Обработчик кнопки редактирования, мы перенаправляем пользователя к /Редактировать/quot_id
Маршрут – но такой маршрут еще не существует. Итак, давайте создадим это первым.
Открыть Arenter.js
и до окончания тега Переключатель
Добавьте еще два маршрута:
... ( )} path="/edit/:id" /> } />
Первый маршрут для EditBook
составная часть. Здесь путь определяется как /Редактировать/: ID
где : id
представляет любой случайный идентификатор.
Второй маршрут – обрабатывать все остальные маршруты, которые не совпадают с упомянутыми маршрутами.
Так что, если мы получим доступ к любому случайному маршруту, как /помощь
или /контакт
Затем мы перенасматриваем пользователь на /
Маршрут, который является Книжный список
составная часть.
Ваш весь Arenter.js
Файл выглядит так сейчас:
import React from 'react'; import { BrowserRouter, Switch, Route } from 'react-router-dom'; import Header from '../components/Header'; import AddBook from '../components/AddBook'; import BooksList from '../components/BooksList'; import useLocalStorage from '../hooks/useLocalStorage'; const AppRouter = () => { const [books, setBooks] = useLocalStorage('books', []); return (); }; export default AppRouter; ( )} path="/" exact={true} /> ( )} path="/add" /> ( )} path="/edit/:id" /> } />
Теперь давайте проверим функциональность редактирования приложения.
Как видите, мы успешно сможете редактировать книгу. Давайте понять, как это работает.
Во-первых, внутри Arenter.js
Файл У нас есть такой маршрут:
( )} path="/edit/:id" />
и внутри Book.js
Файл, у нас есть кнопка редактирования, как это:
Итак, когда мы нажимаем на кнопку редактирования для любого из книг, мы перенаправляем пользователя к EditBook
Компонент с использованием история Метод, передавая идентификатор книги, который необходимо отредактировать.
Тогда внутри EditBook
Компонент, мы используем UseParams
Крюк, предоставленный React-Router-DOM
Для доступа к Props.params.id
Отказ
Так что ниже две линии идентичны.
const { id } = useParams(); // the above line of code is same as the below code const { id } = props.match.params;
Как только мы получили это …| ID Мы используем массив
Найти Метод выяснить конкретную книгу из списка книг с соответствующим предоставленным
ID Отказ
const bookToEdit = books.find((book) => book.id === id);
И эта конкретная книга, которую мы передаем к Bookform
Компонент как книга
проп
Внутри Bookform
Компонент, мы определили состояние, как показано ниже:
const [book, setBook] = useState({ bookname: props.book ? props.book.bookname : '', author: props.book ? props.book.author : '', quantity: props.book ? props.book.quantity : '', price: props.book ? props.book.price : '', date: props.book ? props.book.date : '' });
Здесь мы проверяем, если книга
предпримет существует. Если да, то мы используем детали книги, передаваемой в виде опоры, иначе мы инициализируем состояние с пустым значением ( ''
) для каждого свойства.
И каждый из входных элементов предоставил ценность
опоры, который мы устанавливаем из состояния, как это:
Но мы можем немного улучшить Уместите
Синтаксис внутри Bookform
составная часть.
Вместо непосредственно установки объекта для Уместите
Крюк, мы можем использовать ленивую инициализацию, как сделано в uselocalstorage.js
файл.
Так что измените следующий код:
const [book, setBook] = useState({ bookname: props.book ? props.book.bookname : '', author: props.book ? props.book.author : '', quantity: props.book ? props.book.quantity : '', price: props.book ? props.book.price : '', date: props.book ? props.book.date : '' });
К настоящему коду:
const [book, setBook] = useState(() => { return { bookname: props.book ? props.book.bookname : '', author: props.book ? props.book.author : '', quantity: props.book ? props.book.quantity : '', price: props.book ? props.book.price : '', date: props.book ? props.book.date : '' }; });
Из-за этого изменения кода для настройки состояния не будет выполнено на каждом перезарядке приложения. Он будет просто выполнен один раз, когда компонент установлен.
Если вы проверяете приложение, вы увидите, что приложение работает точно так же, как и раньше, без какой-либо проблемы. Но мы просто улучшили производительность приложений немного.
Как использовать контекст Rection API
Теперь мы закончили построить все функциональность приложения. Но если вы проверяете Arenter.js
Файл, вы увидите, что каждый маршрут выглядит немного сложно. Это потому, что мы проезжаем то же Книги
и Устройства
Подпитывается каждому из компонентов, используя рисунок рендеринга.
Таким образом, мы можем использовать API-контекст React для упрощения этого кода.
Но просто сделать код маршрутизатора проще и дать вам представление о том, как использовать Power Context API, мы будем использовать его в нашем приложении.
Создать новый файл Bookscontext.js
внутри контекст
Папка со следующим содержанием:
import React from 'react'; const BooksContext = React.createContext(); export default BooksContext;
Теперь внутри Arenter.js
Файл, импортируйте вышеупомянутый контекст.
import BooksContext from '../context/BooksContext';
и заменить Rechnouter
Компонент с следующим кодом:
const AppRouter = () => { const [books, setBooks] = useLocalStorage('books', []); return (); }; } />
Здесь мы перевели образец рендеринга реквизита обратно на обычные маршруты и добавили весь Переключатель
Блок внутри Bookscontext.provider
Компонент, как это:
...
Здесь для Bookscontext.provider
Компонент, мы предоставили ценность
Проп, передавая данные, которые мы хотим получить доступ внутри компонентов, упомянутых в маршруте.
Так что теперь каждый компонент, объявленный как часть маршрута, сможет получить доступ к Книги
и Устройства
через контекст API.
Теперь откройте Bookslist.js
Файл и удалить Книги
и Устройства
Реквизиты, которые разрушены, поскольку мы больше не переходим к реквизиту.
Импорт Bookscontext
и упреждающий текст
В верхней части файла:
import React, { useContext } from 'react'; import BooksContext from '../context/BooksContext';
И выше Handleremovebook
Функция, добавьте следующий код:
const { books, setBooks } = useContext(BooksContext);
Здесь мы вынимаем Книги
и Устройства
реквизит от Bookscontext
используя упреждающий текст
крюк.
Ваш весь Bookslist.js
Файл будет выглядеть так:
import React, { useContext } from 'react'; import _ from 'lodash'; import Book from './Book'; import BooksContext from '../context/BooksContext'; const BooksList = () => { const { books, setBooks } = useContext(BooksContext); const handleRemoveBook = (id) => { setBooks(books.filter((book) => book.id !== id)); }; return (); }; export default BooksList; {!_.isEmpty(books) ? ( books.map((book) => ()) ) : ( No books available. Please add some books.
)}
Теперь внесите похожие изменения в Addbood.js
файл.
Ваш весь Addbood.js
Файл будет выглядеть так:
import React, { useContext } from 'react'; import BookForm from './BookForm'; import BooksContext from '../context/BooksContext'; const AddBook = ({ history }) => { const { books, setBooks } = useContext(BooksContext); const handleOnSubmit = (book) => { setBooks([book, ...books]); history.push('/'); }; return (); }; export default AddBook;
Обратите внимание, что здесь мы все еще используем разрушительность для История
пропры Мы только удалили Книги
и Устройства
от разрушительной синтаксиса.
Теперь внесите похожие изменения в EditBook.js
файл.
Ваш весь EditBook.js
Файл будет выглядеть так:
import React, { useContext } from 'react'; import BookForm from './BookForm'; import { useParams } from 'react-router-dom'; import BooksContext from '../context/BooksContext'; const EditBook = ({ history }) => { const { books, setBooks } = useContext(BooksContext); const { id } = useParams(); const bookToEdit = books.find((book) => book.id === id); const handleOnSubmit = (book) => { const filteredBooks = books.filter((book) => book.id !== id); setBooks([book, ...filteredBooks]); history.push('/'); }; return (); }; export default EditBook;
Если вы проверяете приложение, вы увидите, что он работает точно так же, но теперь мы используем API React Context.
Спасибо за прочтение!
Вы можете найти полный исходный код для этого приложения в Этот репозиторий Отказ
Хотите узнать все функции ES6 + подробно, включая пусть и const, обещает, различные методы обещания, массив и деструктурирование объектов, функции стрелки, Async/ждут, импортируют и экспортируют и намного больше с нуля?
Проверьте мой Овладение современным JavaScript книга. Эта книга охватывает все предпосылки для реагирования на обучение и помогает вам стать лучше на JavaScript и реагировать.
Кроме того, вы можете проверить мой Бесплатно Введение в React Router Курс для изучения React Router с нуля.
Хотите остаться в курсе с регулярным контентом в отношении JavaScript, React, Node.js? Следуй за мной на LinkedIn Отказ