ترکیب React و Typescript: اضافه کردن state management

Combining React and Typescript: Adding State Management

25 مرداد 1399
ترکیب React و Typescript: اضافه کردن state management

قبل از اینکه در رابطه با state صحبت کنم باید به سراغ تکمیل مبحث جلسه قبل برویم. در حال حاضر مقدار تایپ شده از کاربر را دریافت کرده ام اما هنوز آن را به app.tsx پاس نداده ایم. چرا به app.tsx؟ در اصل منطق آن به خود شما بستگی دارد اما از آنجایی که app.tsx به هر دو کامپوننت های NewTodo و TodoList دسترسی دارد، انتخاب منطقی تری به نظر می رسد. بنابراین در ابتدا وارد app.tsx شده و یک متد به نام todoAddHandler (نام سلیقه ای است) به آن اضافه کنید:

const App: React.FC = () => {
  const todos = [{ id: 't1', text: 'Finish the course' }];

  const todoAddHandler = (text: string) => {
    console.log(text);
  };
// بقیه کدها //

همانطور که می دانید برای به روز رسانی این آرایه (todos) نمی توانیم فقط خود آن آرایه را تغییر دهیم. در react تغییر دادن آرایه باعث re-render نمی شود بنابراین چیزی به کاربر نمایش داده نمی شود. همانطور که می دانید برای چنین حالاتی باید از state management (مدیریت وضعیت) استفاده کنیم. قبل از انجام این کار فعلا یک دستور log را برای این متد انتخاب کرده ام.

برای اینکه داده ها را در app.tsx دریافت کنیم باید مطمئن شویم که کامپوننت NewTodo می تواند متد todoAddHandler را صدا بزند. برای این کار می توانیم todoAddHandler را به صورت یک prop به NewTodo پاس بدهیم:

const App: React.FC = () => {
  const todos = [{ id: 't1', text: 'Finish the course' }];

  const todoAddHandler = (text: string) => {
    console.log(text);
  };

  return (
    <div className="App">
      <NewTodo onAddTodo={todoAddHandler} />
      <TodoList items={todos} />
    </div>
  );
};

من انتظار دارم که شما با نحوه پاس دادن و کار با prop ها آشنا باشید. حالا به NewTodo.tsx می رویم و در قدم اول باید مطمئن شویم که کامپوننت در حال دریافت prop ها است:

const NewTodo: React.FC = props => {

اگر به جای props در کد بالا پرانتز خالی داشتید، آن ها را حذف کرده و مثل کد بالا props را بنویسید. Props یک پارامتر خاص است که حاوی تمام prop های ما است و توسط react پاس داده می شود.

حالا درون todoSubmitHandler می گوییم:

  const todoSubmitHandler = (event: React.FormEvent) => {
    event.preventDefault();
    const enteredText = textInputRef.current!.value;
    props.onAddTodo(enteredText);
  };

این کد از نظر react صحیح است اما تایپ اسکریپت آن را قبول نمی کند و به ما خطا می دهد. چرا؟ به دلیل اینکه به تایپ اسکریپت اعلام نکرده ایم که قرار است prop ای به نام onAddTodo به این کامپوننت پاس داده شود. بنابراین همان کاری را که برای TodoList انجام دادیم باید برای NewTodo نیز انجام بدهیم؛ تعریف یک interface برای اعلام prop ها به تایپ اسکریپت. فایل NewTodo.tsx را باز کرده و می گوییم:

import React, { useRef } from 'react';

type NewTodoProps = {
  onAddTodo: (todoText: string) => void;
};

همانطور که می بینید ساختار onAddTodo را در قالب یک type تعریف کرده ایم  نه interface. دلیل این کارم این است که متوجه بشوید حتما دلیل خاصی برای استفاده از interface ها نیست و می توانید مانند کد بالا از type شخصی خود استفاده کنید. حالا تعریف NewTodo در همین فایل را به شکل زیر تغییر می دهیم:

const NewTodo: React.FC<NewTodoProps> = props => {

با اضافه کردن NewTodoProps به React.FC خطای تایپ اسکریپت در مورد onAddTodo از بین می رود. حالا اگر برنامه را در مرورگر خود باز کنید و دوباره چیزی را توسط فرم ارسال کنید، مقدار ارسال شده در کنسول مرورگر چاپ می شود اما تفاوت آن با جلسه قبل اینجاست که حالا دارد از کامپوننت App.tsx ارسال می شود (دستور log ما در این کامپوننت است).

اضافه کردن state management

همانطور که گفتم برای ایجاد تغییرات در react نمی توانیم خود آن مقدار (در این پروژه، آرایه todos) را مستقیما تغییر دهیم چرا که این تغییر باعث re-render (پردازش و نمایش دوباره محتویات برنامه) به کاربر نمی شود. راه حل ما اضافه کردن useState است که یکی از hook های مهم در react می باشد. این کار را در فایل App.tsx انجام دهید:

import React, { useState } from 'react';

حالا به جای اینکه آرایه todo را به شکل زیر تعریف کنیم:

  const todos = [{ id: 't1', text: 'Finish the course' }];

باید از useState استفاده کنیم تا یک state اولیه برای ما ایجاد شود. useState همیشه یک آرایه با دو عنصر برمی گرداند: عنصر اول آرایه، آخرین state ما در چرخه Render فعلی است و عنصر دوم آرایه، تابعی است که به ما اجازه می دهد مقدار اول (State) را به روز رسانی کنیم. نکته مهم اینجاست که استفاده از این متد برای به روز رسانی Todos باعث یک re-render می شود بنابراین محتویات برنامه و تغییرات به کاربر نمایش داده می شوند:

const App: React.FC = () => {
  const [todos, setTodos] = useState([]);
// بقیه کدها //

همانطور که در کد بالا می بینید من از Array destructuring استفاده کرده ام تا اعضای اول و دوم آرایه برگردانده شده از useState را با اسم های todos (آخرین state برنامه) و setTodos (متد تغییر دادن state) در اختیار داشته باشم. همچنین در نظر داشته باشید که من یک آرایه خالی را به useState پاس داده ام که یعنی state اولیه ما یک آرایه خالی خواهد بود.

حالا که به متد صحیح تغییر todos (یعنی setTodos) دسترسی داریم می توانیم به جای log کردن مقدار ورودی از سمت کاربر از آن استفاده کنیم. چطور؟ در قسمت بعد این کدها را تکمیل خواهیم کرد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش جامع تایپ اسکریپت توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

ما را دنبال کنید
اینستاگرام روکسو تلگرام روکسو ایمیل و خبرنامه روکسو