ساخت اپلیکیشن یادداشت با React و FaunaDB — از صفر تا صد

۴۸ بازدید
آخرین به‌روزرسانی: ۱۹ شهریور ۱۴۰۲
زمان مطالعه: ۱۲ دقیقه
ساخت اپلیکیشن یادداشت با React و FaunaDB — از صفر تا صد

هم اینک در سال 2020 میلادی هستیم و روش‌های زیادی برای ساخت وب‌اپلیکیشن‌ها وجود دارد. در این مقاله به بررسی روش ساخت اپلیکیشن یادداشت با React و FaunaDB می‌پردازیم و به این ترتیب با یک رویکرد ساخت سریع اپلیکیشن‌های واکنش‌گرا به روشی جذاب آشنا خواهیم شد.

چه چیزی می‌سازیم؟

در این راهنما می‌خواهیم یک اپلیکیشن یادداشت بسازیم، زیرا مثالی خوبی برای نشان دادن شیوه کار React و FaunaDB در کنار هم است.

ساخت اپلیکیشن یادداشت با React و FaunaDB

برای ثبت یادداشت باید کارکردهای CRUD یعنی ایجاد، خواندن، به‌روزرسانی و حذف (create ،read ،update و delete) را پیاده‌سازی کنیم که اساس هر اپلیکیشن مدرنی محسوب می‌شود.

ساخت اپلیکیشن یادداشت با React و FaunaDB

می‌خواهیم یک معماری داشته باشیم که کاربرانمان بتوانند یادداشت جدیدی در آن ایجاد کنند، یادداشت‌های قبلی را ویرایش نمایند و همچنین یادداشت‌ها را از پایگاه داده واکشی کرده و یا حذف نمایند.

سرعت، دقت و امنیت بسیار مهم هستند و از این رو باید بتوانیم مستقیماً از مرورگر با پایگاه داده تعامل پیدا کنیم و از نوشتن و خواندن منسجم در پایگاه داده مطمئن باشیم، یعنی تراکنش‌های تضمین‌شده‌ای داشته باشیم. به همین جهت گزینه‌های FaunaDB و React را برای این پروژه انتخاب کرده‌ایم.

چرا از FaunaDB استفاده می‌کنیم؟

FaunaDB سریع است، به خوبی مقیاس‌بندی می‌شود و کار با آن آسان است. با این که داشتن این مزیت‌ها خوب است، اما بهترین مزیت در مورد انتخاب یک ارائه‌دهنده ابریِ پایگاه داده میزان سهولت آغاز به کار و اجرای آن است. بدین ترتیب به جای صرف ساعت‌ها وقت برای راه‌اندازی و پشتیبانی از پایگاه داده به سادگی با استفاده از FaunaDB همه این موارد در اختیار توسعه‌دهنده قرار می‌گیرد. هر چه تلاش کمتری برای ایجاد زیرساخت صرف کنیم، زمان و انرژی بیشتری برای تمرکز روی ساخت عملی اپلیکیشن خود خواهیم داشت.

بدین ترتیب دیگر لازم نیست در مورد انسجام، مقیاس‌بندی، تهیه کپی، افزونگی داده‌ها و مواردی از این دست تفکر کنیم. FaunaDB همه این وظایف را بر عهده می‌گیرد. به این ترتیب به جای پرداختن به تهیه زیرساخت و فرایند راه‌اندازی می‌توانیم روی هسته مرکزی اپلیکیشن تمرکز کنیم. FaunaDB از پروتکل Calvin (+) برای نگهداری چندین کپی کامل و سازگار از داده‌ها استفاده می‌کند که Replica نام دارد. بدین ترتیب امکان خواندن و نوشتن روی هر گره را پیدا می‌کنیم. هر رپلیکا شامل چندین گره با آگاهی از مکان جغرافیایی خود است که هر یک دارای یک پارتیشن از مجموعه داده‌های کامل در یک محیط لوکال منفرد هستند.

همچنین FaunaDB از احراز هویت از طریق کلیدهای دسترسی، کنترل‌های دسترسی مبتنی بر خصوصیت، مجوزهای سطح وهله نیتیو، TLS/SSL برای پایگاه‌های داده و کلاینت‌ها، جداسازی client/tenant از طریق سلسله‌مراتب پایگاه داده، اولویت‌بندی بارهای کاری و همچنین توکن‌های دسترسی امن برای دسترسی مستقیم کلاینت به پایگاه داده پشتیبانی می‌کند. کلاسترهای client/tenant نیازمند احراز هویت هستند و امکان این که به صورت تصادفی حفاظت نشده رها شوند، وجود ندارد.

چرا از ری‌اکت استفاده می‌کنیم؟

ری‌اکت خود را به عنوان یک کتابخانه فرانت‌اند پیشرو تثبیت کرده است. نکته مهم‌تر این که کار با ری‌اکت و توسعه اپلیکیشن با ری‌اکت کاملاً آسان و جذاب است. البته علاوه بر ری‌اکت چندین راه‌حل مناسب دیگر مانند Vue ،Angular، Svelte و غیره برای این پروژه وجود دارند، اما تا زمانی که کارها به پیش می‌روند مهم نیست که از کدام کتابخانه استفاده می‌کنید. بدون هر گونه توضیح اضافه به سراغ توسعه اپلیکیشن یادداشت خود می‌رویم.

شروع

از آنجا که می‌خواهیم از React و FaunaDB استفاده کنیم، به طور طبیعی باید Node را نصب کنیم.

پیش‌نیازها

  • یک ادیتور متنی (استفاده از ویژوال استودیو کد پیشنهاد می‌شود)
  • نصب Node.js (می‌توانید از طریق وب‌سایت (+) یا ترمینال نصب کنید)
  • ترمینال مبتنی بر یونیکس
  • مرورگر وب

اسکریپت create-react-app

ترمینال خود را باز کرده و با اجرای دستور زیر با استفاده از اسکریپت create-react-app یک اپلیکیشن جدید ری‌اکت ایجاد کنید:

npx create-react-app react-faunadb-note-app && cd react-faunadb-note-app && start

ساخت اپلیکیشن یادداشت با React و FaunaDB

اکنون که پروژه راه‌اندازی شد، پوشه‌ها را ایجاد می‌کنیم. باید دایرکتوری‌های زیر را داشته باشیم:

  • config - همه پایگاه‌های داده مرتبط با منطق در اینجا قرار می‌گیرد.
  • Components - موارد مرتبط با ری‌اکت در آن جای می‌گیرد.
  • api - متدهای واکشی، ویرایش و حذف یادداشت‌ها را در خود جای می‌دهد.

ساخت اپلیکیشن یادداشت با React و FaunaDB

راه‌اندازی FaunaDB

به صفحه ثبت نام وب‌سایت FaunaDB (+) بروید و به عنوان یک کاربر جدید ثبت نام کنید. این کار رایگان است.

ساخت اپلیکیشن یادداشت با React و FaunaDB

زمانی که حساب خود را ایجاد کردید، یک پایگاه داده ایجاد نمایید. ما نام پایگاه خود را notes_app می‌گذاریم:

ساخت اپلیکیشن یادداشت با React و FaunaDB

اکنون که پایگاه داده‌مان ایجاد شد، می‌توانیم کلید دسترسی بسازیم. از این کلیدها برای اتصال و احراز هویت در پایگاه داده استفاده می‌شود. به این ترتیب می‌توانیم کنترل کنیم که چه کسی دسترسی خواندن و نوشتن به پایگاه داده دارد. اما پیش از آن که این کار را انجام دهیم، باید یک «نقش» (role) برای پایگاه داده خود ایجاد کنیم. گزینه‌های نقش در این منو قرار دارند:

console → app → security → roles → new role

ساخت اپلیکیشن یادداشت با React و FaunaDB

سپس به ادامه کار پرداخته و کلید پایگاه داده را ایجاد می‌کنیم. از این کلید برای دسترسی یافتن به پایگاه داده استفاده خواهیم کرد:

console → app → security → keys → new key

ساخت اپلیکیشن یادداشت با React و FaunaDB

زمانی که روی Save کلیک کنید، باید کلید FaunaDB را ببینید.

اپلیکیشن یادداشت با React و FaunaDB

نکته‌ای که باید به خاطر داشته باشید، این است که این کلید دسترسی admin دارد، یعنی اگر کلید نشت یابد، یک خطر امنیتی مهم رخ می‌دهد. کار خود را با کلیدهای کم‌اهمیت‌تر آغاز می‌کنیم.

اپلیکیشن یادداشت با React و FaunaDB

کلید را به ادیتور متنی یا یک مکان امن کپی کنید. در ادامه به آن نیاز خواهیم داشت. ما می‌خواهیم از FaunaDB به عنوان یک پایگاه داده ذخیره‌سازی سند استفاده کنیم. البته گزینه‌های دیگری نیز وجود دارند. از آنجا که هم‌اینک در کنسول هستیم، کلکسیون notes را نیز ایجاد می‌کنیم. منظور از کلکسیون (collection) گروهی از اسناد است. در این پروژه هر یادداشت یک سند است.

اپلیکیشن یادداشت با React و FaunaDB اپلیکیشن یادداشت با React و FaunaDB

زمانی که کلکسیون ایجاد شد، FaunaDB به صورت پیش‌فرض اقدام به اندیس کردن سند می‌کند.

اپلیکیشن یادداشت با React و FaunaDB

اندیس‌ها ساختارهای ذخیره‌سازی هستند که از سوی سیستم پایگاه داده برای تسهیل بازیابی مؤثر زیرمجموعه‌ای از داده‌ها استفاده می‌شوند. طراحی اسکیمای کارآمد FaunaDB موجب شده که از هر دو مزیت پشتیبانی درجه اول از مدل‌سازی رابطه‌ای و اندیس‌های متریال پشتیبانی کند.

ایجاد ارتباط بین ری‌اکت و یک وهله از FaunaDB

اکنون که همه چیز در سمت FaunaDB آماده است، به بررسی بخش ری‌اکت می‌پردازیم.

نصب وابستگی‌ها

باید تا حد امکان تلاش کنیم از کدهای موجود، استفاده مجدد داشته باشیم، چون این کار موجب آسان‌تر شدن کارها و افزایش سرعت توسعه می‌شود. در این بخش از چند کتابخانه محبوب استفاده می‌کنیم. اپلیکیشن ما وابستگی‌های زیر را دارد:

  • Faunadb – درایور جاوا اسکریپت FaunaDB
  • antd - زبان طراحی UI در کلاس سازمانی و کتابخانه رابط کاربری ری‌اکت
  • react-toastify – موجب تسهیل ارسال نوتیفیکیشن ری‌اکت می‌شود.

اپلیکیشن یادداشت با React و FaunaDB

ایجاد فایل env.

از آنجا که نمی‌خواهیم کلیدها و توکن‌هایمان با وارد شدن درون ریپازیتوری به بیرون نشت یابند، باید از فایل‌های env. استفاده کنیم.

اپلیکیشن یادداشت با React و FaunaDB در ادامه فایل env. را به gitignore. اضافه می‌کنیم. env.example. باید بدون مقدار به ریپازیتوری پوش شود.

اپلیکیشن یادداشت با React و FaunaDB

مطمئن شوید که YOURKEYHERE را با کلید FaunaDB عوض کرده‌اید. سپس سرور را ری‌استارت کنید. به این ترتیب از هم اکنون از طریق مقدار process.env.REACT_APP_FAUNADB_KEY به کلید FaunaDB دسترسی داریم. هم اینک معماری پروژه ما باید چیزی مانند زیر باشد:

اپلیکیشن یادداشت با React و FaunaDB

 ایجاد ارتباط اولیه با FaunaDB

تا به اینجا مسیری نسبتاً طولانی آمده‌ایم و اینک زمان آن فرا رسیده است که یک ارتباط با پایگاه داده خود بگیریم. بنابراین یک فایل به نام db.js درون دایرکتوری config می‌سازیم:

1import faunadb from 'faunadb'
2
3const client = new faunadb.Client({ secret: process.env.REACT_APP_FAUNADB_KEY })
4const q = faunadb.query
5
6export { client , q }

پس از برقراری ارتباط می‌توانیم شروع به کوئری زدن به FaunaDB بکنیم. آیا دایرکتوری api را که قبلاً متذکر شدیم، به خاطر دارید؟ این همان جایی است که همه منطق مرتبط با کوئری‌ها را در آن قرار می‌دهیم. به این ترتیب می‌توانیم چیزی مانند ()fetchAllNotes را درون کامپوننت ری‌اکت فراخوانی کنیم. این کار را به این جهت انجام می‌دهیم که دغدغه‌ها را هم جدا کنیم تا خواندن و درک کامپوننت ری‌اکت آسان شود.

نوشتن کوئری‌های FaunaDB

این اپلیکیشن یادداشت به کاربران اجازه می‌دهد که یادداشت‌ها را ایجاد کرده، ویرایش و حذف کنند و یا همه آن‌ها را از سرور واکشی نمایند. کار را با واکشی همه یادداشت‌ها از کلکسیون آغاز می‌کنیم.

واکشی همه یادداشت‌ها

1import { client, q } from '../config/db'
2
3const getAllNotes = client.query(
4  q.Paginate(
5    q.Match(
6      q.Ref('indexes/all_notes')))
7)
8  .then(response => {
9    const notesRefs = response.data
10    // create new query out of notes refs. 
11    // https://docs.fauna.com/fauna/current/api/fql/
12    const getAllProductDataQuery = notesRefs.map((ref) => {
13      return q.Get(ref)
14    })
15    // query the refs
16    return client.query(getAllProductDataQuery).then((data) => data)
17  })
18  .catch(error => console.warn('error', error.message))
19
20export default getAllNotes;

ممکن است فکر کنید کد فوق حجم بالایی دارد، اما کارکرد آن نسبتاً ساده است. در ادامه این کارکرد را به تفصیل شرح می‌دهیم:

  • ابتدا پایگاه داده FaunaDB و وهله کوئری ایمپورت می‌شود.
  • با استفاده از اندیس notes به همه یادداشت‌ها کوئری می‌زنیم. این کوئری همه ref-ها را بازگشت می‌دهد که روی آن نگاشت کرده و نتایج را بازگشت می‌دهیم.
  • در صورت بروز خطای شبکه آن خطا را دریافت کرده و هشداری را لاگ می‌کنیم این حالت در زمانی که می‌خواهیم بازخوردی به کاربر بدهیم مفید خواهد بود.

توجه کنید که ما از Promise-های ناهمگام استفاده می‌کنیم. اگر این مفهوم برای شما جدید است می‌توانید راهنمای زیر را مطالعه کنید:

ویرایش کردن یک یادداشت

ویرایش کردن رکوردهای FaunaDB آسان است. تنها کاری که باید انجام دهیم فراخوانی کوئری Update با ID مرجع و مقدار جدید است.

1import { client, q } from '../config/db'
2
3const editNote = (noteId, newText) => client.query(
4  q.Update(
5    q.Ref(q.Collection('notes'), noteId),
6    { data: { text: newText } },
7  )
8)
9.then((ret) => console.log(ret))
10.catch(err => console.warn(err))
11
12
13export default editNote

این کوئری را درون یک تابع قرار دادیم که دو آرگومان می‌گیرد. یکی از آرگومان‌ها noteId است که می‌خواهیم ویرایش کنیم و دیگری مقدار متن جدید است.

حذف کردن یک یادداشت

حذف کردن یک یادداشت نیز مشابه ویرایش کردن آن است. کافی است کوئری Delete را با ID مرجع یادداشت فراخوانی کنیم.

1const deleteNote = noteRef => client.query(
2
3q.Delete(q.Ref(q.Collection('notes'), noteRef))
4
5)
6
7.then(res => res)
8
9.catch(err => console.warn(err.message))
10
11export default deleteNote

ایجاد یک یادداشت

در نهایت کد کوئری FaunaDB برای افزودن یک یادداشت جدید به کلکسیون به صورت زیر است:

1import { client, q } from '../config/db'
2
3const createNote = text => client.query(
4  q.Create(
5    q.Collection('notes'),
6    {
7      data: {
8        text
9      },
10    },
11  )
12)
13.then(ret => ret)
14.catch(err => console.warn(err))
15
16
17export default createNote

توجه کنید که FaunaDB کوئری‌های خود را به صورت منطقی مانند q.Create ،q.Delete ،q.Update و غیره نامگذاری کرده است.

اکسپورت کردن کوئری‌ها

اکنون که نوشتن کد کوئری‌ها را به پایان بردیم، نوبت آن رسیده است که کوئری‌ها را اکسپورت کنیم تا بتوانیم از آن‌ها درون کامپوننت‌های ری‌اکت استفاده کنیم. در ادامه فایلی به نام index.js درون دایرکتوری api ایجاد می‌کنیم:

1import getAllNotes from './getAllNotes'
2import createNote from './createNote'
3import deleteNote from './deleteNote'
4import editNote from './editNote';
5
6export { getAllNotes, createNote, deleteNote, editNote }

کد فوق به ما امکان می‌دهد که به جای نوشتن خطوط کدهای ایمپورت، این کار را در یک خط به صورت زیر انجام دهیم:

import { getAllNotes, deleteNote, editNote, createNote } from ‘./api’

فراخوانی کوئری‌های FaunaDB با ری‌اکت

تنها کاری که باقی مانده است، فراخوانی کردن کوئری‌های FaunaDB و رندر کردن نتایج است. کار را با باز کردن فایل App.js و نوشتن کد زیر در آن آغاز می‌کنیم:

1import React, { useEffect, useState } from 'react';
2import './App.css';
3import { getAllNotes, deleteNote, editNote } from './api'
4
5function App() {
6  
7  const [notes, setNotes] = useState([])
8
9  useEffect(() => {
10    getAllNotes.then(res => setNotes(res))
11  }, [])
12
13  return (
14    <div className="App">
15      <header className="App-container">
16        <div className="notes-container">
17           
18        </div>
19      </header>
20    </div>
21  );
22}
23
24export default App;

در کد فوق کارهای زیر انجام می‌شوند:

  • کوئری‌های FaunaDB از دایرکتوری api ایمپورت می‌شوند.
  • با استفاده از قلاب useState یک «حالت» (State) برای یادداشت‌ها ایجاد می‌شود.

اگر در مورد قلاب‌های ری‌اکت اطلاعات کمی دارید، پیشنهاد می‌کنیم مطلب زیر را مطالعه کنید:

اعتبارسنجی فرم با قلاب‌های React — به زبان ساده

  • در ادامه درون قلاب useEffects اقدام به فراخوانی getAllNotes می‌کنیم. این قلاب بی‌درنگ پیش از نصب کامپوننت فراخوانی می‌شود.

نتیجه بازگشتی کوئری به صورت زیر است. نتیجه را به صورت حالت notes ذخیره کرده و با ری‌اکت رندر می‌کنیم:

اپلیکیشن یادداشت با React

شاید کنجکاو باشید که این timestamp-ها به چه چیزی مربوط هستند. FaunaDB این موارد را ردگیری می‌کند، چون دارای یک نسخه‌بندی داخلی است. شما می‌توانید در صورت نیاز سابقه هر یادداشت را نیز کوئری کنید.

ایجاد یادداشت‌ها

در این بخش فایل‌های زیر را در دایرکتوری components ایجاد می‌کنیم:

اپلیکیشن یادداشت با React

  • NoteForm.js – این فایل برای ایجاد یادداشت‌های جدید استفاده می‌شود.
  • NoteList.js - همه یادداشت‌ها را رندر کرده و کارکردهای مرتبط با یادداشت‌ها مانند ویرایش و حذف را نمایش می‌دهد.
  • Index.js – برای ایمپورت و اکسپورت استفاده می‌شود.

در ادامه ابتدا فایل NoteForm.js را ایجاد می‌کنیم:

1import React from 'react'
2import { Form, Button, Input } from 'antd';
3import { createNote } from '../api'
4
5const NoteForm = ({ form, notes, setNotes }) => {
6
7  const { getFieldDecorator, validateFields, resetFields } = form;
8
9  function handleSubmit(e) {
10    e.preventDefault();
11  }
12  
13  
14  return (
15    <Form style={{marginBottom: '25px'}} layout="horizontal" onSubmit={handleSubmit}>
16      <Form.Item>
17        {getFieldDecorator('note', {
18        rules: [],
19        })(
20          <Input
21            className="note-input"
22            size="large"
23            placeholder="Add New Note"
24          />,
25          <Button>Create</Button>
26        )}
27      </Form.Item>
28
29  </Form>
30  )
31}
32
33const WrappedNoteForm = Form.create({name: 'notes_form'})(NoteForm)
34
35export default WrappedNoteForm;

توجه کنید که در انتهای فایل کامپوننت NoteForm را درون کامپوننت مرتبه بالاتر (HOC) به نام Form با طراحی Ant قرار داده‌ایم. بدین ترتیب می‌توانیم از تزریق استفاده کنیم و به prop فرم از درون کامپوننت NoteForm دسترسی پیدا می‌کنیم. مشخصه from شامل متدهایی برای اعتبارسنجی فرم است. بدین منظور از متدهای getFieldDecorator ،validateFields و resetFields استفاده می‌کنیم.

پیاده‌سازی مدیریت تحویل فرم

1const NoteForm = ({ form, notes, setNotes }) => {
2
3  const { getFieldDecorator, validateFields, resetFields } = form;
4
5  function handleSubmit(e) {
6    e.preventDefault();
7    validateFields((err, values) => {
8      if (!err && values.note) {
9        createNote(values.note).then(res => {
10          const newNotesArray = notes.concat([res])
11          setNotes(newNotesArray)
12          toast.success('Added Successfully')
13          resetFields()
14        })
15      }
16    });
17  }
18  
19  ... //
20}

در این بخش به اعتبارسنجی فرم می‌پردازیم. اگر هیچ خطایی در فرم نباشد و دست‌کم یک کاراکتر در آن وجود داشته باشد، فرم را تحویل می‌دهیم و با کوئری زدن به وهله FaunaDB می‌خواهیم که این یادداشت را ذخیره کند. توجه کنید که ما از prop-های notes و setNotes استفاده می‌کنیم. ما باید این موارد را از App.js استفاده کنیم. اگر بیشتر دقت کنید متوجه می‌شوید که مقادیر را از اشیای props و form می‌گیریم. اکنون اقدام به ایمپورت کامپوننت‌ها در index.js می‌کنیم تا بتوانیم آن‌ها را به شیوه‌ای آسان در پروژه ایمپورت کنیم.

1import NoteList from './NoteList'
2import NoteForm from './NoteForm'
3
4export { NoteList, NoteForm }

استایل‌بندی

ما برای اپلیکیشن خود استایل‌های زیر را ایجاد کرده‌ایم. محتوای زیر را در فایل App.css کپی کنید. البته می‌توانید بسته به سلیقه خود هر نوع تغییری که مطلوب می‌دانید را روی آن اعمال کنید:

1.App {
2  text-align: center;
3  min-height: 100vh;
4  display: flex;
5  margin: 75px 0 25px;
6  flex-direction: flex-start;
7  align-items: flex-start;
8  justify-content: center;
9  font-size: calc(10px + 2vmin);
10}
11
12.App-container {
13  width: 100%;
14  margin: 0 auto;
15  text-align: center;
16  display: flex;
17  flex-direction: column;
18  align-items: center;
19}
20
21.note-row p {
22  margin: 0 34px 0 0;
23  padding: 0;
24  outline: none;
25  min-width: 250px;
26}
27
28.note-input {
29  height: 32px;
30  border: none;
31  padding: 5px 20px;
32  min-width: 250px;
33  border-radius: 4.5px;
34  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
35  outline: none;
36}
37
38.notes-container {
39  display: flex;
40  flex-direction: column;
41  align-items: space-between;
42}
43
44.note-row {
45  margin: 12px 0;
46  display: flex;
47  justify-content: flex-start;
48  align-items: center;
49  text-align: left;
50}

استفاده از کامپوننت NoteForm

اینک زمان آن فرا رسیده است که از کامپوننت NoteForm استفاده کنیم. این کامپوننت را در فایل App.js ایمپورت کنید:

1import React, { useEffect, useState  } from 'react';
2import './App.css';
3import { getAllNotes, deleteNote, editNote } from './api'
4import { NoteList, NoteForm } from './components'
5
6function App() {
7  
8  const [notes, setNotes] = useState([])
9
10  useEffect(() => {
11    getAllNotes.then(res => setNotes(res))
12  }, [])
13
14  return (
15    <div className="App">
16      <header className="App-container">
17        <div className="notes-container">
18          <NoteForm notes={notes} setNotes={setNotes} />
19        </div>
20      </header>
21    </div>
22  );
23}
24
25export default App;

فراموش نکنید که props را به کامپوننت NoteForm ارسال کنید. اینک باید در مرورگر نتیجه‌ای مانند تصویر زیر داشته باشید:

اپلیکیشن یادداشت با React

اینک فرم کار می‌کند، اما نتایج هنوز رندر نمی‌شوند. این مشکل را نیز اصلاح می‌کنیم. فایل کامپوننت NoteList.js را باز کرده و کد زیر را در آن بنویسید:

1import React, { useEffect, useState  } from 'react';
2import './App.css';
3import { getAllNotes, deleteNote, editNote } from './api'
4import { NoteList, NoteForm } from './components'
5
6function App() {
7  
8  const [notes, setNotes] = useState([])
9
10  useEffect(() => {
11    getAllNotes.then(res => setNotes(res))
12  }, [])
13
14  return (
15    <div className="App">
16      <header className="App-container">
17        <div className="notes-container">
18          <NoteForm notes={notes} setNotes={setNotes} />
19        </div>
20      </header>
21    </div>
22  );
23}
24
25export default App;

به این ترتیب همه یادداشت‌ها را نگاشت کرده و رندر می‌کنیم. برای هر یادداشت شنونده‌های رویدادی اضافه می‌کنیم تا ویرایش شدن محتوا و حذف شدن یادداشت‌ها را متوجه شویم. NoteList را در App ایمپورت کرده و آن را زیر کامپوننت NoteForm قرار دهید:

1import React, { useEffect, useState  } from 'react';
2import './App.css';
3import { getAllNotes, deleteNote, editNote } from './api'
4import { NoteList, NoteForm } from './components'
5
6function App() {
7  
8  const [notes, setNotes] = useState([])
9
10  useEffect(() => {
11    getAllNotes.then(res => setNotes(res))
12  }, [])
13
14  function handleRemove(e, id) {
15    e.preventDefault();
16    deleteNote(id).then(res => res)
17    const newNotesArray = notes.filter(note => note.ref.id !== id)
18    setNotes(newNotesArray)
19    toast.success('Removed successfully')
20  }
21
22  function handleEdit(e, id, newText) {
23    e.preventDefault();
24    editNote(id, newText).then(res => res)
25  }
26
27  return (
28    <div className="App">
29      <header className="App-container">
30        <div className="notes-container">
31          <NoteForm notes={notes} setNotes={setNotes} />
32          <NoteList 
33            onEdit={handleEdit} 
34            onRemove={handleRemove} 
35            data={notes}
36          />
37        </div>
38      </header>
39    </div>
40  );
41}
42
43export default App;

همچنین پیاده‌سازی متدهای handleRemove و handleEdit را فراموش نکنید. آن‌ها را به صورت prop به کامپوننت NoteList ارسال کنید. اینک مرورگر را باز کرده و چیزی در NoteForm نوشته و اینتر را بزنید. به این ترتیب نتیجه‌ای مانند زیر می‌بینید:

اپلیکیشن یادداشت با React

اینک اگر کلکسیون FaunaDB را بررسی کنیم، می‌بینیم که یادداشت‌های جدیدی درج شده‌اند. تلاش کنید یادداشت‌های جدیدی ایجاد کرده و آن‌ها را ویرایش یا حذف کنید.

اپلیکیشن یادداشت با React

اگر مشکلی پیش نیامد به این معنی است که ما پروژه خود را با موفقیت اجرا کرده‌ایم.

موارد اختیاری: افزودن نوتیفیکیشن Toast

اگر می‌خواهید زمانی که کاربر یادداشت‌ها را درج یا حذف می‌کند، نوتیفیکیشن‌هایی روی صفحه ظاهر شوند، به روش زیر عمل کنید:

1import { ToastContainer, toast } from 'react-toastify';
2import 'react-toastify/dist/ReactToastify.css';
3
4function App() {
5
6 //stuff here
7  return (
8    <div className="App">
9      <ToastContainer />
10      <header className="App-container">
11         // stuff here
12      </header>
13    </div>
14  );
15  
16}

در کد فوق:

  • ابتدا استایل ها را ایمپورت کرده ToastContainer را نیز از کتابخانه react-toastify ایمپورت کرده‌ایم.
  • ToastContainer درون متد return قرار گرفته است. بدین ترتیب به نوتیفیکیشن Toast دسترسی می‌یابیم. اکنون می‌توانیم با فراخوانی toast.success(‘message here’) یا toast.error(‘error message’) از هر جایی در اپلیکیشن نوتیفیکیشن بسازیم. با قرار دادن پیام‌های Toast در متد handleRemove کد فوق را تست کنید. فراموش نکنید که هر جا می‌خواهید از آن استفاده کنید، باید متد toast را از پکیج ایمپورت کنید.
import { toast } from 'react-toastify';
1function handleRemove(e, id) {
2  // stuff here
3  toast.success('Removed successfully')
4}

اکنون اگر روی آیکون حذف کلیک کنید، یک toast می‌بینید:

اپلیکیشن یادداشت با React

برای دسترسی به کد کامل این پروژه به این ریپوی گیت‌هاب (+) بروید.

نکته مهم: با توجه به مقاصد آموزشی این راهنما، این اپلیکیشن به همه کاربران اجازه می‌دهد که به وب‌سایت دسترسی یابند و یادداشت‌هایی ایجاد کرده و بخوانند. در سناریوهای واقعی این وضعیت به دلایل امنیتی مطلوب نیست. به طور معمول باید اپلیکیشن را در پشت یک صفحه امنیتی لاگین قرار دهیم که تابع لاگین FaunaDB یا راه‌کارهای دیگر را پیاده‌سازی می‌کند.

سخن پایانی

از این که این راهنما را تا به انتهای پیگیری کردید متشکریم. امیدواریم با مطالعه این مقاله موارد جدیدی آموخته باشید. هر گونه نظر و پیشنهاد خود را می‌توانید در بخش نظرات این نوشته با ما و دیگر خوانندگان مجله در میان بگذارید.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۰ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
better-programming
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *