Мені дуже сподобалося додавати цю маленьку функціональність до мого React застосунку DinoFinder2020, який був моїм фінальним проєктом для Flatiron School.
Я ніколи не був повністю задоволений цим застосунком. Хоча це був мій фінальний проєкт, я трохи поспішав, щоб встигнути закінчити навчання вчасно, і він так і не став таким відшліфованим, як мені хотілося. Це графічна вікі для каталогізації доісторичних тварин. Але ідея цікава, і я справді хотів, щоб вона виглядала добре, тому я протягом останніх кількох тижнів вносив косметичні правки.
Коли я шукав в Google «додати підтвердження видалення до react застосунку», нічого, що дійсно відповідало моїм потребам або чітко пояснювало, наскільки це просто, я не знайшов. Я почав слідувати інструкціям в одному з посібників, але їхній випадок був набагато складнішим за мій, і це не мало сенсу. Тому я зробив кілька кроків назад і почав знову, і тоді зрозумів, наскільки це неймовірно просто, використовуючи react-bootstrap і передаючи деякі пропси.
Отже, я створив новий файл компонента, DeleteConfirm.js, в папці src\components. Цей компонент буде моїм спливаючим вікном для підтвердження, чи справді ви хочете видалити запис. React-bootstrap має компонент Modal, який чудово підходить для цієї мети. Тож вам потрібно додати імпорти на початку нового компонента наступним чином:
import React from 'react';import { Modal, Button } from "react-bootstrap";
У мене є ще один імпорт, deleteButton, але до цього ми повернемося трохи пізніше. Коли імпорти готові, потрібно спроектувати ваш модаль. Документація react-bootstrap дуже добре це пояснює. Ви навіть можете просто скопіювати і вставити їхній приклад коду, хоча вам доведеться внести деякі зміни, починаючи з перших кількох рядків:
const [show, setShow] = useState(false);const handleClose = () => setShow(false);const handleShow = () => setShow(true);
Це хуки (hooks), і їх, ймовірно, краще розмістити в батьківському компоненті. Чому? Тому що кнопка, яка насправді буде викликати модаль, є частиною іншого компонента, і ця кнопка повинна мати доступ до цих хуків. Тому я зробив компонент DeleteConfirm дочірнім для DinosaurCard.
Використання цього як батьківського компонента дозволить передавати корисну інформацію до DeleteConfirm і, звісно, змінити вашу оригінальну кнопку видалення, щоб вона більше не змінювала базу даних, а лише викликала модаль для підтвердження. Не забувайте, якщо ви використовуєте функціональний компонент для батька, як я, вам потрібно імпортувати хук useState:
import { useState } from "react";
Отже, я це зробив і передав своєму новому дочірньому компоненту деякі пропси:
Перші три з них ви вже бачили в попередньому фрагменті коду — тепер вони є частиною стану DinosaurCard і передаються до Modal як пропси. Якщо ви скопіювали приклад з react-bootstrap, вам потрібно буде повідомити Modal, що ці значення тепер є пропсами, тому замість:
Ви будете мати:
І так далі для кожного іншого випадку show та handleClose. Не забувайте фактично вставити новий компонент у return батьківського компонента.
Коли все це зроблено, ви повинні мати змогу натискати кнопку в вашому батьківському компоненті і викликати дочірній компонент модалі точно так, як це показано в прикладі react-bootstrap. Ось що я маю на увазі, коли кажу, що це просто — я буквально просто використав приклад коду і розділив його на два компоненти, щоб вони могли взаємодіяти один з одним. Але... зараз у нас є тільки модаль, яка нічого не робить.
Як змусити це насправді видалити запис? Ось тут і виникає пропс handleDelete. Ця функція насправді вже була в моєму застосунку до того, як я реалізував цю модаль, це функція, яка фізично видаляє запис з бази даних. Я розмістив її в своєму вищому компоненті DinosaurContainer і так залишив. Спочатку я передавав її до DinosaurCard, а потім ще нижче до DeleteButton, функціонального компонента, який виконує лише одну задачу — видаляє запис. Можна посперечатися, чи дійсно потрібен окремий компонент для цього, це міг би бути просто компонент DinosaurCard. Але я люблю тримати все гнучким, тому створив окремий компонент. І цей компонент все одно робив те, що мені потрібно було, викликав функцію handleDelete і видаляв запис. Тому замість того, щоб використовувати цей компонент (який видаляв запис без попередження) в DinosaurCard, я помістив його в DeleteConfirm.
Тепер кнопка видалення в DinosaurCard викликає модаль, яка запитує, чи справді ви хочете видалити. Потім модаль (DeleteConfirm) показує вам оригінальний компонент кнопки видалення, на яку можна натискати, щоб підтвердити бажання видалити.
roar?
В основному я перепризначив свій оригінальний компонент кнопки видалення і змінив кнопку видалення в картці на таку, що викликає модаль, а не відразу видаляє. Легко й швидко!
Знаю, що це трохи переросло в rant, специфічний для мого проєкту, тому спробую підсумувати це нижче:
- Створіть нову гілку в git (необов'язково, але рекомендовано).
- Створіть новий функціональний компонент. Скопіюйте і вставте код з прикладу на цій сторінці в ваш новий компонент.
- Виріжте весь код, що стосується локального стану, з компонента і вставте його в той компонент, який буде показувати початкову кнопку видалення (кнопку, що викликає модаль). Не забудьте імпортувати useState, якщо це функціональний компонент.
- Замість вашої оригінальної початкової кнопки видалення поставте просту кнопку, яка лише викликає модаль. Переконайтеся, що її onClick = {handleShow}. Але збережіть код для вашої оригінальної кнопки, він знадобиться через кілька кроків.
- Додайте новий компонент з модаллю до батьківського компонента, передаючи як пропси show, handleClose і будь-які інші дані, які потрібні вашій модалі. На цьому етапі ви повинні мати змогу натискати вашу початкову кнопку видалення і бачити новий компонент модалі.
- Цей посібник припускає, що у вас уже є реалізована функціональність видалення. Візьміть ту кнопку, яку ви використовували для видалення запису раніше, і вставте її в новий компонент модалі. Я замінив кнопку 'click here to save' з прикладу на мій компонент DeleteButton, але ви могли б навіть залишити її, змінити текст на 'confirm delete' і додати вашу фактичну функцію видалення в її onClick. Головне, щоб одна з кнопок у модалі викликала вашу функцію видалення — тоді все працює.
- Зафіксуйте ваш код і об'єднайте з гілкою master. Ось і все!
На жаль, це не універсальний підхід, і вам, ймовірно, доведеться налаштувати ці інструкції під вашу конкретну реалізацію, але я сподіваюся, що я зробив їх достатньо загальними, щоб навіть ті, як я, хто просто хоче отримати просте підтвердження перед видаленням одного з записів в React, змогли слідувати цим крокам і реалізувати це.
Дякую за прочитання і успіхів у кодуванні!
Перекладено з: Adding a Delete Confirmation to your React App