هوک useState ری اکت و بررسی تخصصی ()React.useState

·

7 min read

هوک useState ری اکت به ما این امکان رو میده که حالت ها و مقادیر کامپوننت خودمون رو در جایی ذخیره کنیم. این حالت ها (stateها) میتونن از هر نوعی ( string,number,array,object و..) باشن .

با ذخیره کردن این state ها ، میتونیم تو کل اون کامپوننت ازشون مثل یه متغیر استفاده کنیم و هر زمان نیاز داشتیم مقدارشون رو بروزرسانی کنیم .

هوک useState چطور کار میکنه ؟

با ساختن هر state ( توسط useState ) باید یک مقدار اولیه به اون state بدید .

مثلا اگه میخواید Theme اپیکیشن رو داخل state ذخیره کنید ، باید مشخص کنید که مقدار اولیه Theme چی باشه ؟!

تو مثال زیر ما به کمک هوک useState حالت اپیکیشن رو ذخیره کردیم.
(تو این مثال از theme برای دسترسی به مقدار و از setTheme برای بروز کردن مقدار استفاده میکنیم ):

const [theme,setTheme] = useState('DarkMode')

اگه کد بالارو کامل متوجه نشدید ، اصلا نگران نباشید و با فِرانت اِندی همراه باشید که میخوایم حسابی بررسیش کنیم 🙂

هوک useState ری اکت چیست ؟

هوک useState یکی از مهمترین هوک های ری اکت هست که به ما اجازه میده حالت های کامپوننت خودمون رو ذخیره و مدیریت کنیم . حالا شاید بپرسید حالت کامپوننت یعنی چی ؟

فرض کنید توی کامپوننت خودمون باید نام کاربر یا شماره تلفنش رو در جایی ذخیره کنیم . خب هرکدوم از اینها یک حالت ( state ) هستن که هوک useState ری اکت به ما امکان ذخیره و بروزرسانی این مقادیر رو میده.

برای ذخیره کردن نام کاربر باید بصورت زیر عمل کنیم :

const [name,setName] = useState('احمد')

برای استفاده از نام کاربر تو کامپوننت خودمون ، باید از name استفاده کنیم . مثل مثال زیر :

<div>{name}</div>

برای تغییر یا بروزرسانی مقدار name به یک مقدار جدید ( مثلا تغییر احمد به حسین ) باید بصورت زیر عمل کنیم :

setName('حسین')

در واقع React.useState به ما 2 امکان میده :

  • امکان خواندن مقدار ذخیره شده .

  • امکان بروزرسانی مقدار ذخیره شده.

هوک useState ری اکت چه مقادیری رو میتونه ذخیره کنه ؟

هوک useState در React به ما اجازه ذخیره هر نوع مقداری با هر نوعی رو میده !

مثلا شما میتونید انواع مختلف دیتا های primitive مثل String , Number , Boolean رو داخلش ذخیره کنید . همچنین امکان ذخیره کردن دیتا های Complex مثل Array و Object ، تابع ، و دیتا تایپ های اختصاصی روهم دارید.

یا بزارید اینجوری بگم :

هرچیزی که داخل متغیر های جاوااسکریپت میتونید ذخیره کنید ، داخل State هم میتونید 🙂

اما بروزرسانی Object و Array کمی متفاوت تره !

تو ری اکت انواع مختلف دیتا رو میشه بصورت مستقیم بروزرسانی کرد ( مثل مثال های بالا )

اما برای Object و Array نمیشه مستقیما بروزرسانی رو انجام داد . ( بخاطر بحث immutability که بعدا راجبش صحبت میکنیم )

برای بروزرسانی Object یا Array باید بصورت زیر عمل کنید :

  1. یک کپی از Object یا Array موجود در state بگیرید .

  2. تغییرات خودتون رو روی اون Object یا Array کپی شده اعمال کنید .

  3. حالا توسط setState آبجکت یا آرایه بروز شده رو در state ذخیره کنید .

تو دستورالعمل بالا ما مستقیما مقدار State خودمون با نوع Object یا Array رو آپدیت نمیکنیم !

یک کپی از اون مقدار میگیریم و هر تغییری که لازم داریم رو روی اون مقدار کپی شده لحاظ میکنیم .

حالا مقدار کپی شده که تغییرات رو هم شامل شده ، توسط setState جایگزین مقدار قبلی در state میکنیم .

تو مثال زیر یه State با نوع Object رو بروزرسانی میکنیم :

const [state, setState] = useState({ name: 'Fatemeh', age: 21 });

const updateAge = () => {
  setState({ ...state, age: 22 });
};

تو مثال بالا یه State داریم که یک Object به عنوان مقدار اولیه ( InitialState ) بهش دادیم . این آبجکت شامل نام و سن هست که نام از نوع رشته و سن از نوع عدد هستن.

تابع updateAge برای بروزرسانی اطلاعات این State هست که داخلش setState رو صدا زدیم .

با state… میتونیم یک کپی از مقدار state بگیریم ، حالا چون مقدار age تغییر کرده پس در کنارش مقدار جدید رو هم قرار میدیم .

یعنی تو خط 4 گفتیم : از هرچی تو state هست یه کپی بگیر ، حالا مقدار age رو توی ورژن کپی شده تغییر بده . در نهایت با setState این مقدار بروز شده رو set کن .

تو مثال زیر یه state با نوع Array رو بروزرسانی میکنیم :

const [array, setArray] = useState([1, 2, 3, 4, 5]);

const addItem = () => {
  setArray([...array, 6]);
};

تو مثال بالا یک state از نوع Array داریم .

تو خط 4 یک کپی از array گرفتیم و مقدار 6 رو به این آرایه اضافه کردیم و در نهایت توسط setArray این مقدار بروزر شده رو set کردیم .

چه زمانی باید از ()React.useState استفاده کنیم ؟

بطور کل زمانیکه میخوایم حالت ها یا مقادیر مرتبط به یک کامپوننت رو بصورت داخلی ذخیره کنیم ، باید از هوک ()useState استفاده کنیم .

اما اگه حالت یا وضعیتی که میخوایم ذخیره کنیم داخلی نیست ، باید از State Management هایی مثل Redux استفاده کنیم. ( داخلی نیست یعنی از یه state تو کل اپیکیشن و کامپوننت های مختلف استفاده کنیم )

چطور از ()useState استفاده کنیم ؟

برای استفاده از این هوک خفن باید اون رو import کنیم ( فراخوانی کنیم ) :

import React, { useState } from 'react';

مقدار اولیه useState یا همون initialState چیه ؟

همونطور که قبلا هم گفتیم ، موقع استفاده از هوک useState باید یک مقدار اولیه بهش بدیم .

اما یه جاهایی از مقدار اولیه خبر نداریم !!

مثلا قراره از یک API ، مقداری رو بگیرید و داخل state بعنوان initialState قرار بدید . و خب چون نمیدونیم مقداری که اون API میخواد برگردونه چیه و چقدر زمان میبره ، نمیتونیم موقع تعریف بهش مقداری رو به عنوان مقدار اولیه بدیم .

در اینجا از تکنیکی به عنوان Lazily Initialize استفاده میکنیم .

در واقع Lazily Initialize مواقعی کاربرد داره که مقدار اولیه ما با تاخیر باید Initialize ( مقدار دهی اولیه ) بشه .

تو مثال زیر از useState استفاده کردیم اما بعنوان مقدار اولیه ، یک Function بهش دادیم :

const userDetail= () => {
   const [state,setState] = useState( () => myApiCallFunction() );
}

تو مثال بالا یه نکته مهم وجود داره ، اینکه مقدار اولیه ای که با تکنیک Lazily Initialize قرار دادیم ، فقط در render اولیه قرار میگیره.

بروزرسانی State با setState در ری اکت !

هوک useState از ما 2 آرگومان میگیره . مقدار اول برای خواندن مقدار اون state و مقدار دوم یک تابع برای بروزرسانی مقدار اون state هست .

تو مثال زیر یک کامپوننت به اسم User داریم و قراره نام کاربر رو داخل یک State به نام name ذخیره کنیم . دقت کنید که این مقدار توسط یک Input از خود کاربر دریافت میشه و توسط onChange داخل state قرار میگیره .

const User = () => {
  const [name,setName] = useState('');

  return (
    <div>
      <input
         type="text"
         value={name}
          onChange={e => setName(e.target.value)}
          placeholder="نام خودتون رو وارد کنید"
       />
      <p>
        <strong>میباشد.{name}نام شما</strong>
      </p>
    </div>
  );
}; //

گاهی اوغات نیاز میشه که state خودمون رو با توجه به مقدار قبلی اون state بروزرسانی کنیم .

مثلا میخوایم با هربار کلیک روی دکمه ، مقدار state به علاوه 1 بشه . انجام اینکار مستلزم بررسی مقدار قبلی state هست .

تو مثال زیر همون مثال بالایی رو اوردیم ، با این تفاوت که قراره با توجه به مقدار قبلی state ، عملیات setState رو انجام بدیم :

const User = () => {
  const [name,setName] = useState('');

  return (
    <div>
      <input
         type="text"
         value={message}
          onChange={(e)=>setName(prev=>prev+e.target.value)}
          placeholder="نام خودتون رو وارد کنید"
       />
      <p>
        <strong>میباشد.{name}نام شما</strong>
      </p>
    </div>
  );
}; //

استفاده از هوک useState برای ذخیره کردن Object

چند تا نکته تخصصی و مهم راجب State هایی که نوع Object دارن وجود داره که هرکسی به این نکات توجه نمیکنه.

نکته اول :

برای اینکه نکته اول رو بگم ، State زیر که نوعش Object هست رو در نظر بگیرید :

const [user,setUser]=useState({name:'Ahmad'',phone:09111111111});

حالا فرض کنید کد زیر رو اجرا کنیم یعنی setUser با همون مقدار user !

setUser({...user})

شاید فکر کنین اینجا re-Render صورت میگیره اما اینطور نیست .در واقع ری اکت تو پشت صحنه از تابع ()Object.is استفاده میکنه و متوجه میشه که State جدید با State قبلی یکسانه ! پس re-Redner صورت نمیگیره 🙂

نکته دوم :

لطفا برای مطالعه ادامه این مقاله در وبسایت فِرانت اِندی روی لینک زیر کلیک کنید :

useState در ری اکت