استفاده از localStorage با هوک‌های React

در این مقاله قصد داریم تا نحوه استفاده از localStorage برای تداوم ورودی فرم کاربر در حافظه مرورگر با استفاده از هوک‌های React را پوشش دهیم. همچنین نحوه ساخت یک هوک سفارشی React برای به اشتراک گذاشتن منطق مشابه بین چندین کامپوننت را بررسی خواهیم کرد.

localStorage چیست؟

localStorage یکی از دو مکانیسم ذخیره‌سازی وب مرورگر است. این کار به کاربران اجازه می‌دهد تا داده‌ها را به عنوان جفت‌های key-value برای استفاده بعدی در مرورگر ذخیره کنند.

برخلاف مکانیسم

sessionStorage
sessionStorage که تا زمانی که تب مرورگر فعلی در حال اجرا است داده‌ها را در حافظه مرورگر نگه می‌دارد، localStorage وقتی مرورگر بسته می‌شود، داده‌ها را پاک نمی‌کند. این موضوع آن را برای داده‌های ماندگار که به تب مرورگر فعلی محدود نمی‌شوند ایده‌آل می‌کند.

توسعه‌دهندگان معمولاً هنگام افزودن یک ویژگی مانند افزودن حالت دارک مود به یک برنامه، تداوم یک آیتم to-do یا حفظ مقادیر ورودی فرم کاربر یا موارد دیگر، از localStorage استفاده می‌کنند.

راه‌اندازی اولیه پروژه localStorage

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npx create-react-app localstorage-react-hook
npx create-react-app localstorage-react-hook
npx create-react-app localstorage-react-hook

همچنین می‌توانیم برای راحتی بیشتر، راه‌اندازی پروژه را با استفاده از vite نیز انجام دهیم.

پس از ایجاد پوشه پروژه، آن را در IDE باز می‌کنیم و با اجرای دستور

npm start
npm start سرور توسعه را راه‌اندازی می‌نماییم. پروژه در آدرس مرورگر
http://localhost:3000/
http://localhost:3000/ راه‌اندازی می‌شود.

ساخت یک کامپوننت فرم React

همانطور که قبلا به آن اشاره کردیم، ما از localStorage استفاده می‌کنیم تا مقادیری که کاربر در فرم برنامه React وارد می‌کند را در حافظه مرورگر حفظ نماییم.

مانند هر برنامه Reactای، تمرکز ما بر روی پوشه

src
src است. بنابراین، تمام فایل‌های داخل
src
src را حذف می‌کنیم و یک فایل
index.js
index.js در داخل پوشه
src
src می‌سازیم. سپس کد زیر را به
index.js
index.js اضافه می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
// styles
import "./app.css";
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
import React from "react"; import ReactDOM from "react-dom"; import App from "./components/App"; // styles import "./app.css"; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById("root") );
import React from "react";
import ReactDOM from "react-dom";

import App from "./components/App";
// styles
import "./app.css";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

همینطور برای این که برنامه ظاهری زیبایی داشته باشد می‌توانیم یک فایل

app.css
app.css در پوشه
src
src ایجاد کرده و کد‌های css موجود در این لینک را در آن قرار دهیم.

سپس یک پوشه

components
components در پوشه
src
src ایجاد می‌کنیم تا فایل‌های کامپوننت را در آن قرار دهیم. پس از آن، یک فایل
App.js
App.js و یک فایل
Form1.js
Form1.js می‌سازیم. فایل
App.js
App.js کامپوننت root و parent برنامه است و فایل
Form1.js
Form1.js ورودی‌های فرم را نگه می‌دارد.

کد زیر را به فایل

components/App.js
components/App.js اضافه می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import Form1 from "./Form1";
const App = () => {
return (
<div className="container">
<h1>localStorage with React hooks</h1>
<Form1 />
</div>
);
};
export default App;
import Form1 from "./Form1"; const App = () => { return ( <div className="container"> <h1>localStorage with React hooks</h1> <Form1 /> </div> ); }; export default App;
import Form1 from "./Form1";

const App = () => {
  return (
    <div className="container">
      <h1>localStorage with React hooks</h1>
      <Form1 />
    </div>
  );
};
export default App;

و در نهایت کدی که در ادامه داریم را در فایل

components/Form1.js
components/Form1.js قرار می‌دهیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState } from "react";
const Form1 = () => {
const [name, setName] = useState("");
return (
<form>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Full name"
aria-label="fullname"
/>
<input type="submit" value="Submit"></input>
</form>
);
};
export default Form1;
import { useState } from "react"; const Form1 = () => { const [name, setName] = useState(""); return ( <form> <input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder="Full name" aria-label="fullname" /> <input type="submit" value="Submit"></input> </form> ); }; export default Form1;
import { useState } from "react";

const Form1 = () => {
  const [name, setName] = useState("");

  return (
    <form>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Full name"
        aria-label="fullname"
      />
      <input type="submit" value="Submit"></input>
    </form>
  );
};

export default Form1;

کد بالا ساده‌ترین پیاده‌سازی inputهای فرم در React است. با استفاده از هوک

useState
useState کامپوننتی که داریم را کنترل می‌کنیم و state ورودی را بعد از هر تغییری که اتفاق می‌افتد، به‌روز نگه می‌داریم.

اما، هنگامی که ما صفحه را رفرش می‌کنیم، همانطور که انتظار داریم داده‌های ورودی پاک می‌شوند. برای تداوم داده‌های ورودی به طوری که در بارگذاری مجدد صفحه یا در بازدیدهای بعدی در دسترس باشد، باید آن‌ها را در localStorage ذخیره کنیم.

ذخیرهسازی داده‌های input فرم در localStorage

localStorage به ما امکان دسترسی به آبجکت

Storage
Storage مرورگر را می‌دهد. آبجکت
Storage
Storage دارای متدهایی برای ذخیره‌سازی، خواندن و حذف داده‌ها و بسیاری از اکشن‎‌های دیگر است.

برای مشاهده لیستی از متدهای

Storage
Storage، کنسول مرورگر را باز کرده و localStorage را تایپ می‌کنیم. پس از فشار دادن enter، متدها در
prototype
prototype آبجکت
Storage
Storage در دسترس قرار می‌گیرند.

استفاده از متد ()setItem

برای ذخیره داده‌های ورودی فرم در حافظه مرورگر، باید متد

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
localStorage.setItem("key", "value")
localStorage.setItem("key", "value")
localStorage.setItem("key", "value")

storage
storage مرورگر فقط data-typeهای از نوع رشته را می‌پذیرد. بنابراین، برای مقادیر data-typeهای مختلف مانند آبجکت یا آرایه، باید آن را با استفاده از
JSON.stringify()
JSON.stringify() به یک رشته JSON تبدیل نماییم.

استفاده از هوک useEffect برای انجام side effectها

ما می‌توانیم از هوک

useEffect برای انجام side effectهایی مانند ذخیره‌سازی داده‌ها در حافظه مرورگر استفاده کنیم. این اتفاق باعث می‌شود که هوک
useEffect
useEffect مکان مناسبی برای فراخوانی متد
setItem
setItem باشد.

فایل

components/Form1.js
components/Form1.js را باز می‌کنیم و کد زیر را بالای عبارت
return
return اضافه می‌نماییم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
useEffect(() => {
// storing input name
localStorage.setItem("name", JSON.stringify(name));
}, [name]);
useEffect(() => { // storing input name localStorage.setItem("name", JSON.stringify(name)); }, [name]);
useEffect(() => {
  // storing input name
  localStorage.setItem("name", JSON.stringify(name));
}, [name]);

باید مطمئن شویم که

useEffect
useEffect را از React به صورت زیر import کرده باشیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState, useEffect } from "react";
import { useState, useEffect } from "react";
import { useState, useEffect } from "react";

در اینجا ما یک key

"name"
"name" و یک value داینامیک از متغیر state، که
name
name است را اختصاص داده‌ایم. مقدار اولیه متغیر state
name
name به صورت پیش‌فرض یک رشته خالی است:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const [name, setName] = useState("");
const [name, setName] = useState("");
const [name, setName] = useState("");

استفاده از

JSON.stringify
JSON.stringify در
setItem
setItem هنگام ذخیره‌سازی داده‌های string در حافظه اختیاری است:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
localStorage.setItem("name", JSON.stringify(name));
localStorage.setItem("name", JSON.stringify(name));
localStorage.setItem("name", JSON.stringify(name));

با این حال، اگر value از نوع داده‌ای متفاوتی مانند یک آبجکت یا آرایه باشد،

JSON.stringify
JSON.stringify لازم است. اکنون اگر پروژه را تست کنیم می‌بینیم که با هر تغییری که در input صورت می‌گیرد، value آن در local storage ذخیره می‌شود. زیرا، هوک
useEffect
useEffect که متد ذخیره‌سازی
setItem
setItem را در خود دارد، در اولین رندر کامپوننت و پس از هر تغییر state اجرا می‌شود.

با این حال، در هر بار بارگذاری مجدد صفحه، value موجود در حافظه پاک می‌شود. این اتفاق می‌افتد زیرا ما یک رشته خالی پیش‌فرض را به متغیر state

name
name اختصاص داده‌ایم. بنابراین، React از آن string خالی در رندر اولیه استفاده می‌کند.

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

خواندن داده‌ها از localStorage

در بارگذاری اولیه صفحه، به جای اختصاص دادن یک رشته خالی به متغیر state

name
name، باید تابعی را اختصاص دهیم که به حافظه محلی دسترسی داشته باشد، مقدار ذخیره شده را بازیابی کند و از آن به عنوان مقدار پیش‌فرض استفاده نماید.

استفاده از متد ()getItem

هوک

useState
useState را در فایل
components/Form1.js
components/Form1.js به‌روزرسانی می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const [name, setName] = useState(() => {
// getting stored value
const saved = localStorage.getItem("name");
const initialValue = JSON.parse(saved);
return initialValue || "";
});
const [name, setName] = useState(() => { // getting stored value const saved = localStorage.getItem("name"); const initialValue = JSON.parse(saved); return initialValue || ""; });
const [name, setName] = useState(() => {
  // getting stored value
  const saved = localStorage.getItem("name");
  const initialValue = JSON.parse(saved);
  return initialValue || "";
});

در این کد، ما از متد

getItem()
getItem() storage برای بازیابی داده‌ها از حافظه محلی استفاده می‌کنیم.
JSON.parse()
JSON.parse() مورد استفاده در کد، رشته JSON بازگشتی را از فضای ذخیره‌سازی جدا می‌کند. هر دو
JSON.stringify
JSON.stringify و
JSON.parse
JSON.parse هنگام کار با مقادیر رشته اختیاری هستند اما، انواع داده‌های دیگر، مانند آبجکت‌ها و آرایه‌ها، به آن‌ها نیاز دارند.

فایل را ذخیره کرده و پروژه را تست می‌کنیم. این بار داده‌های ورودی input باید در فیلد فرم در بارگذاری مجدد صفحه یا پس بازدید از صفحه دیگر همچنان موجود باشند.

ساخت یک هوک سفارشی برای ماندگاری مقادری ورودی فرم

گاهی اوقات ممکن است بخواهیم ورودی‌های فرم بیشتری، مانند ورودی متن و ورودی checkbox را در یک کامپوننت دیگری رندر کرده و آن‌ها را داشته باشیم.

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

در عوض، React به ما این امکان را می‌دهد تا با استفاده از هوک‌های سفارشی، منطق مشابهی را extract کرده و بین کامپوننت‌ها به اشتراک بگذاریم. هدف ما در این بخش این است که نحوه ایجاد یک هوک سفارشی برای ماندگاری مقادیر ورودی فرم‌ها در چندین کامپوننت را با هم بررسی کنیم.

در پوشه

src/components
src/components یک فایل جدید به نام
Form2.js
Form2.js ایجاد کرده و کد زیر را به اضافه می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState } from "react";
const Form2 = () => {
const [name, setName] = useState("");
const [checked, setChecked] = useState(false);
return (
<form>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Full name"
aria-label="fullname"
/>
<label>
<input
type="checkbox"
checked={checked}
onChange={(e) => setChecked(e.target.checked)}
/>{" "}
Not a robot?
</label>
<input type="submit" value="Submit"></input>
</form>
);
};
export default Form2;
import { useState } from "react"; const Form2 = () => { const [name, setName] = useState(""); const [checked, setChecked] = useState(false); return ( <form> <input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder="Full name" aria-label="fullname" /> <label> <input type="checkbox" checked={checked} onChange={(e) => setChecked(e.target.checked)} />{" "} Not a robot? </label> <input type="submit" value="Submit"></input> </form> ); }; export default Form2;
import { useState } from "react";

const Form2 = () => {
  const [name, setName] = useState("");
  const [checked, setChecked] = useState(false);

  return (
    <form>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Full name"
        aria-label="fullname"
      />
      <label>
        <input
          type="checkbox"
          checked={checked}
          onChange={(e) => setChecked(e.target.checked)}
        />{" "}
        Not a robot?
      </label>
      <input type="submit" value="Submit"></input>
    </form>
  );
};

export default Form2;

سپس، کامپوننت را در فایل

components/App.js
components/App.js وارد کرده و از آن استفاده می‌نماییم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// ...
import Form2 from "./Form2";
const App = () => {
return (
<div className="container">
{/* ... */}
<Form2 />
</div>
);
};
export default App;
// ... import Form2 from "./Form2"; const App = () => { return ( <div className="container"> {/* ... */} <Form2 /> </div> ); }; export default App;
// ...
import Form2 from "./Form2";

const App = () => {
  return (
    <div className="container">
      {/* ... */}
      <Form2 />
    </div>
  );
};
export default App;

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

Extract کردن منطق localStorage

برای شروع extract منطق localStorage، یک فایل به نام

useLocalStorage.js
useLocalStorage.js در پوشه
src
src ایجاد کرده و کد زیر را به آن می‌افزاییم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState, useEffect } from "react";
function getStorageValue(key, defaultValue) {
// getting stored value
const saved = localStorage.getItem(key);
const initial = JSON.parse(saved);
return initial || defaultValue;
}
export const useLocalStorage = (key, defaultValue) => {
const [value, setValue] = useState(() => {
return getStorageValue(key, defaultValue);
});
useEffect(() => {
// storing input name
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
};
import { useState, useEffect } from "react"; function getStorageValue(key, defaultValue) { // getting stored value const saved = localStorage.getItem(key); const initial = JSON.parse(saved); return initial || defaultValue; } export const useLocalStorage = (key, defaultValue) => { const [value, setValue] = useState(() => { return getStorageValue(key, defaultValue); }); useEffect(() => { // storing input name localStorage.setItem(key, JSON.stringify(value)); }, [key, value]); return [value, setValue]; };
import { useState, useEffect } from "react";

function getStorageValue(key, defaultValue) {
  // getting stored value
  const saved = localStorage.getItem(key);
  const initial = JSON.parse(saved);
  return initial || defaultValue;
}

export const useLocalStorage = (key, defaultValue) => {
  const [value, setValue] = useState(() => {
    return getStorageValue(key, defaultValue);
  });

  useEffect(() => {
    // storing input name
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
};

اگر در کد بالا دقت کنیم می‌بینیم که ما فقط منطق ذخیره‌سازی را از فایل

components/Form1.js
components/Form1.js extract کرده‌ایم.

با ایجاد یک هوک سفارشی به نام

useLocalStorage
useLocalStorage، تمام منطق ذخیره‌سازی که در کامپوننت
Form1
Form1 داریم را حفظ می‌کنیم. باید به این نکته توجه داشته باشیم که می‌توانیم برای نام‌گذاری هوک سفارشی خود از هر نامی استفاده کنیم اما حتما باید در ابتدای نام از
use
use استفاده کرده باشیم.

هوک

useLocalStorage
useLocalStorage دو آرگومان دارد:
key
key و
defaultValue
defaultValue. این بدان معنی است که ما باید هنگام فراخوانی این هوک در کامپوننت‌های مختلف، این مقادیر را حتما به آن پاس بدهیم.

استفاده از هوک سفارشی useLocalStorage

در فایل

components/Form1.js
components/Form1.js، منطق بالای عبارت
return
return را با هوک سفارشی جایگزین می‌کنیم تا موارد زیر را داشته باشیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useLocalStorage } from "../useLocalStorage";
const Form1 = () => {
const [name, setName] = useLocalStorage("name", "");
return (
<form>
{/* ... */}
</form>
);
};
export default Form1;
import { useLocalStorage } from "../useLocalStorage"; const Form1 = () => { const [name, setName] = useLocalStorage("name", ""); return ( <form> {/* ... */} </form> ); }; export default Form1;
import { useLocalStorage } from "../useLocalStorage";

const Form1 = () => {
  const [name, setName] = useLocalStorage("name", "");

  return (
    <form>
      {/* ... */}
    </form>
  );
};

export default Form1;

پس از import کردن هوک سفارشی، می‌توانیم از آن استفاده کرده و key منحصربه‌فرد و value پیش‌فرض را که در این مثال یک رشته خالی است، ارسال کنیم.

اگر همین کار را برای کامپوننت

Form2
Form2 در فایل
components/Form2js
components/Form2js انجام دهیم، باید کدی که داریم به صورت کد زیر باشد:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useLocalStorage } from "../useLocalStorage";
const Form2 = () => {
const [name, setName] = useLocalStorage("name2", "");
const [checked, setChecked] = useLocalStorage("checked", false);
return (
<form>
{/* ... */}
</form>
);
};
export default Form2;
import { useLocalStorage } from "../useLocalStorage"; const Form2 = () => { const [name, setName] = useLocalStorage("name2", ""); const [checked, setChecked] = useLocalStorage("checked", false); return ( <form> {/* ... */} </form> ); }; export default Form2;
import { useLocalStorage } from "../useLocalStorage";

const Form2 = () => {
  const [name, setName] = useLocalStorage("name2", "");
  const [checked, setChecked] = useLocalStorage("checked", false);

  return (
    <form>
      {/* ... */}
    </form>
  );
};

export default Form2;

اکنون اگر پروژه را تست کنیم می‌توانیم در قسمت localStorage مرورگر مشاهده کنیم که تمام ورودی‌های فرم را ذخیره کرده‌ایم.

بررسی مشکلات دسترسی به localStorage برای یک برنامه SSR

هنگام کار با فریم‌ورک‌هایی مانند Next.js که کد را در سمت سرور اجرا می‌کند، استفاده از localStorage خطایی ایجاد می‌کند تحت عنوان

window is not defined.
window is not defined..

localStorage، همانطور که در کد برنامه React خود از آن استفاده کردیم، یک ویژگی built-in از آبجکت

window
window یعنی
window.localStorage
window.localStorage است. ما در کد خود، هنگام دسترسی به localStorage
window
window را نادیده گرفتیم زیرا یک آبجکت سراسری است. یعنی می‌توانیم انتخاب کنیم که آبجکت
window
window به کد اضافه شود یا خیر، زیرا اختیاری می‌باشد.

اکنون، این آبجکت

window
window در سمت سرور در دسترس نیست، و فقط در سمت کلاینت یا مرورگر موجود است و همین دلیل باعث بروز خطا می‌شود. برای رفع خطا در سمت سرور، بررسی می‌کنیم که آیا آبجکت
window
window تعریف شده است یا خیر. به این ترتیب کد ما فقط در محیطی که
window
window در دسترس است اجرا می‌شود.

فایل

src/useLocalStorage.js
src/useLocalStorage.js را باز کرده و تابع
getStorageValue()
getStorageValue() را به‌روزرسانی می‌کنیم تا موارد زیر را داشته باشد:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function getStorageValue(key, defaultValue) {
// getting stored value
if (typeof window !== "undefined") {
const saved = localStorage.getItem(key);
const initial = saved !== null ? JSON.parse(saved) : defaultValue;
return initial;
}
}
function getStorageValue(key, defaultValue) { // getting stored value if (typeof window !== "undefined") { const saved = localStorage.getItem(key); const initial = saved !== null ? JSON.parse(saved) : defaultValue; return initial; } }
function getStorageValue(key, defaultValue) {
  // getting stored value
  if (typeof window !== "undefined") {
    const saved = localStorage.getItem(key);
    const initial = saved !== null ? JSON.parse(saved) : defaultValue;
    return initial;
  }
}

نباید فراموش کنیم که ما از localStorage در داخل هوک

useEffect
useEffect در فایل
useLocalStorage.js
useLocalStorage.js نیز استفاده کرده‌ایم. اما در این مورد، localStorage دچار خطا نمی‌شود زیرا، هوک
useEffect
useEffect فقط در سمت کلاینت اجرا می‌شود و در آن جا دسترسی به آبجکت
window
window وجود دارد.

بررسی مشکلات رایج هنگام استفاده از localStorage

نحوه مدیریت localStorage تعریف نشده

خطای

localStorage is not defined
localStorage is not defined در React به این دلیل رخ می‌دهد که localStorage یک API ذخیره‌سازی وب مخصوص مرورگر است. این خطا عمدتاً زمانی رخ می‌دهد که از یک فانکشنالیتی مخصوص مرورگر در محیطی که تعریف نشده است استفاده می‌کنیم. به عنوان مثال، اگر کد ما در سمت سرور اجرا شود که localStorage در آن تعریف نشده است در این صورت با خطا مواجه می‌شویم. برای رفع این خطا چندین راه حل داریم که عبارتند از:

  • بررسی در دسترس بودن localStorage: می‌توانیم این کار را با قرار دادن کد خود در یک عبارت شرطی (
    if...else
    if...else) یا با بررسی اینکه آیا
    window.localStorage
    window.localStorage تعریف شده است یا خیر، انجام دهیم.
  • سازگاری مرورگر: این خطا ممکن است خیلی به ندرت اتفاق بیفتد اما باز هم غیرممکن نیست. زیرا ممکن است مرورگرهای قدیمی API localStorage را پیاده‌سازی نکرده باشند، در صورتی که کد ما بدون بررسی مناسب به آن متکی باشد، در نتیجه منجر به ایجاد این خطا می‌شود. بنابراین، باید جایگزین‌هایی مانند کوکی‌ها و ذخیره‌سازی سمت سرور را در نظر بگیریم.
  • تشخیص ویژگی: می‌توانیم از تشخیص ویژگی برای سازگاری گسترده‌تر یا ارائه مکانیزم بازگشتی استفاده کنیم. این موضوع به ما کمک می‌کند تا بتوانیم به طور خودکار جایگزین‌هایی را برای محیط‌های بدون ذخیره سازی محلی ارائه دهیم.

نحوه پاکسازی موثر localStorage در React

پاک کردن localStorage جفت‌های key-value ذخیره شده توسط برنامه ما را حذف می‌کند، بنابراین مهم است که این کار را فقط زمانی انجام دهیم که از آن مطمئن هستیم. برای پاک کردن localStorage در React، دو راه اصلی وجود دارد:

  • متد
    localStorage.clear()
    localStorage.clear(): استفاده از این متد ساده‌ترین و سریع‌ترین راه برای پاک کردن localStorage است، زیرا هر چیزی که در آن دامنه ذخیره شده باشد را پاک می‌کند. سینتکس آن
    localStorage.clear();
    localStorage.clear(); است.
  • متد
    .removeItem()
    .removeItem(): این متد یک key مشخص شده را از فضای localStorage دامنه حذف می‌کند. در نتیجه می‌توانیم کنترل بیشتری بر روی موارد حذف شده داشته باشیم. استفاده از این متد نیز بسیار ساده است و ما باید نام key را برای حذف ارسال کنیم و سینتکس آن
    localStorage.removeItem(key)
    localStorage.removeItem(key) می‌باشد.

بررسی سوالات متداول درمورد localStorage و هوک‌های React

چگونه می‌توانیم یک هوک سفارشی برای localStorage ایجاد کنیم؟

استفاده از هوک‌های سفارشی React برای localStorage بهترین گزینه نیستند. اما با این حال، موارد استفاده و مزایای خود را دارند.

در این مثال، نحوه ایجاد یک هوک سفارشی برای localStorage با استفاده از هوک‌های

useEffect
useEffect و
useState
useState را بررسی می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState, useEffect } from 'react';
export default function useLS(key, defaultValue) {
const [value, setValue] = useState(() => {
const storedValue = localStorage.getItem(key);
if (storedValue) {
return JSON.parse(storedValue);
}
return defaultValue;
});
useEffect(() => {
if (value === undefined) return;
localStorage.setItem(key, JSON.stringify(value));
}, [value, key]);
return [value, setValue];
}
export default useLS;
import { useState, useEffect } from 'react'; export default function useLS(key, defaultValue) { const [value, setValue] = useState(() => { const storedValue = localStorage.getItem(key); if (storedValue) { return JSON.parse(storedValue); } return defaultValue; }); useEffect(() => { if (value === undefined) return; localStorage.setItem(key, JSON.stringify(value)); }, [value, key]); return [value, setValue]; } export default useLS;
import { useState, useEffect } from 'react';

export default function useLS(key, defaultValue) {
  const [value, setValue] = useState(() => {
    const storedValue = localStorage.getItem(key);
    if (storedValue) {
      return JSON.parse(storedValue);
    }
    return defaultValue;
  });

  useEffect(() => {
    if (value === undefined) return;
    localStorage.setItem(key, JSON.stringify(value));
  }, [value, key]);

  return [value, setValue];
}

export default useLS;

کد بالا یک هوک سفارشی به نام

useLS
useLS است که امکان ذخیره‌سازی و بازیابی داده‌ها از حافظه محلی مرورگر با استفاده از هوک‌های
useState
useState و
useEffect
useEffect را فراهم می‌کند. این هوک سفارشی دو آرگومان می‌گیرد که عبارتند از:
key
key و
defaultValue
defaultValue. هوک
useState
useState داده‌ها را از localStorage بازیابی می‌کند، آن‌ها را parse کرده و درصورت
null
null بودن مقدار،
defaultValue
defaultValue را return می‌کند.

useLS
useLS مقدار فعلی ذخیره شده در localStorage برای یک
key
key معین و یک تابع برای به‌روزرسانی value را return می‌کند.

چگونه می‌توانیم در React داده‌ها را از localStorage دریافت کنیم؟

می‌توانیم دریافت داده از localStorage را با استفاده از متد

.getItem(key)
.getItem(key) در React انجام دهیم. این متد value مربوط به key که آن را به متد ارسال می‌کنیم، بازیابی می‌کند و سینتکس آن به این صورت است:
localStorage.getItem(your key)
localStorage.getItem(your key)

جمع‌بندی

ما در این مقاله سعی کردیم تا نحوه استفاده از localStorage برای ماندگاری داده‌ها در مرورگر با استفاده از هوک‌های React را بررسی کنیم. همچنین با این مفهوم که چگونه می‌توانیم یک هوک سفارشی برای extract کردن منطق کامپوننت در توابع با قابلیت استفاده مجدد آشنا شدیم.

در نهایت، دسترسی به کدهایی که در این مقاله آن‌ها را بررسی کردیم از طریق این لینک امکان‌پذیر می‌باشد.

دیدگاه‌ها:

افزودن دیدگاه جدید