← Back to React Course | Chapter 6: Custom Hooks & Advanced Patterns | Lesson 3 of 10

useLocalStorage Hook बनाना

एक useLocalStorage hook एक notebook जैसा है जो याद रखता है कि आपने क्या लिखा था even browser tab बंद करने और बाद में वापस आने के बाद भी।
Syntax
markup
function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    // read the saved value or use initialValue
  });
  useEffect(() => {
    // write value back to localStorage
  }, [key, value]);
  return [value, setValue];
}

Why Sync State with localStorage

Normal React state हर बार page reload होने पर reset होता है, क्योंकि यह सिर्फ memory में रहता है। localStorage data को browser में persist करता है even tab बंद होने के बाद भी।

एक useLocalStorage hook दोनों को combine करता है, तो एक value normal state जैसा behave करती है लेकिन एक refresh भी survive करती है।

Note:
  • Good use cases हैं:
  • theme preference
  • एक saved draft
  • 'remember me' style settings — कुछ भी जिसे आप एक reload survive करवाना चाहते हैं।
Warning: Sensitive data (जैसे tokens या passwords) localStorage में store न करें — यह page पर चलने वाले किसी भी JavaScript द्वारा readable है, malicious scripts सहित।

उदाहरण: Why Sync State with localStorage

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function useLocalStorage(key, initialValue) {
  const [value, setValue] = React.useState(() => {
    const saved = localStorage.getItem(key);
    return saved !== null ? JSON.parse(saved) : initialValue;
  });
  React.useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);
  return [value, setValue];
}
function App() {
  const [name, setName] = useLocalStorage("name", "Guest");
  return <input value={name} onChange={e => setName(e.target.value)} />;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Reading the Saved Value on First Render

useState अपनी initial value के रूप में एक function accept करता है (जिसे lazy initializer कहा जाता है), जो सिर्फ पहले render पर एक बार run होता है। localStorage में पहले से saved value check करने की यह सही जगह है, क्योंकि इसे function body में directly check करना हर render पर run होता।

Note: हमेशा useState को एक function pass करें (() => ...) directly localStorage.getItem() को argument के रूप में call करने के बजाय, हर render पर storage फिर से पढ़ने से बचने के लिए।
Warning: अगर stored JSON malformed है (जैसे devtools में manually edit किया गया), JSON.parse throw करेगा — initial value पर fall back करने के लिए इसे try/catch में wrap करें।

उदाहरण: Reading the Saved Value on First Render

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function useLocalStorage(key, initialValue) {
  const [value] = React.useState(() => {
    try {
      const saved = localStorage.getItem(key);
      return saved !== null ? JSON.parse(saved) : initialValue;
    } catch { return initialValue; }
  });
  return value;
}
function App() {
  const count = useLocalStorage("count", 0);
  return <p>Loaded count: {count}</p>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Writing Back on Every Change

State value watch करने वाला एक useEffect हर बार इसके change होने पर इसे localStorage में JSON.stringify उपयोग करके वापस लिखता है, क्योंकि localStorage सिर्फ strings store कर सकता है। यह saved copy को हमेशा current React state के साथ sync में रखता है।

Note: Dependency array में key और value दोनों शामिल करें ताकि hook सही रहे even अगर key खुद dynamic हो।
Warning: एक fast-changing input के हर keystroke पर localStorage में लिखना wasteful हो सकता है — बड़ी या frequently-changing values के लिए write को debounce करने पर consider करें।

उदाहरण: Writing Back on Every Change

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function useLocalStorage(key, initialValue) {
  const [value, setValue] = React.useState(initialValue);
  React.useEffect(() => { localStorage.setItem(key, JSON.stringify(value)); }, [key, value]);
  return [value, setValue];
}
function App() {
  const [notes, setNotes] = useLocalStorage("notes", "");
  return (
    <div>
      <textarea value={notes} onChange={e => setNotes(e.target.value)} />
      <p>Saved: {notes.length} characters</p>
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. यह भूल जाना कि localStorage सिर्फ strings store करता है, इसलिए objects/arrays को save करने से पहले JSON.stringify और वापस पढ़ते समय JSON.parse करना चाहिए।
  2. localStorage access को try/catch में wrap न करना, जो private browsing mode में या storage full होने पर throw कर सकता है।
  3. State के दो अलग pieces के लिए same localStorage key उपयोग करना, उन्हें silently एक-दूसरे को overwrite करवाते हुए।
चैप्टर सारांश
  • useLocalStorage एक custom hook है जो React state के एक piece को browser के localStorage के साथ sync करता है।
  • यह initial render पर saved value पढ़ता है और state change होने पर वापस localStorage में लिखता है।
  • JSON.stringify/JSON.parse चाहिए क्योंकि localStorage सिर्फ strings store करता है।
  • यह pattern commonly theme preferences, form drafts, और छोटे settings के लिए उपयोग होता है जिन्हें एक page refresh survive करना चाहिए।
ब्राउज़र सपोर्ट

React 16.8 (Hooks introduction) से available है; localStorage खुद सभी modern browsers में supported है (IE8+)।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.