ਬਿਨਾਂ ਮਤਲਬ ਦੇ ਕੰਪੋਨੈਂਟਸ ਦੀਆਂ ਪਰਤਾਂ ਰਾਹੀਂ props pass ਕਰਨਾ ਬਹੁਤ ਥਕਾਊ ਕੰਮ ਹੈ। ਇੱਕ ਦਿਨ ਤੁਸੀਂ ਕੋਈ ਫੀਚਰ ਲਾਂਚ ਕਰ ਰਹੇ ਹੁੰਦੇ ਹੋ, ਅਤੇ ਅਗਲੇ ਹੀ ਦਿਨ ਸਿਰਫ਼ ਇੱਕ prop ਦਾ ਨਾਮ ਬਦਲਣ ਲਈ ਤੁਹਾਨੂੰ ਛੇ ਫਾਈਲਾਂ ਐਡਿਟ ਕਰਨੀਆਂ ਪੈਂਦੀਆਂ ਹਨ। ਸੰਖੇਪ ਵਿੱਚ, ਇਹੀ prop drilling ਹੈ: ਇੱਕ parent ਕੋਲ ਡੇਟਾ ਹੈ, ਇੱਕ ਡੂੰਘੇ child ਨੂੰ ਉਸਦੀ ਲੋੜ ਹੈ, ਅਤੇ ਉਹਨਾਂ ਦੇ ਵਿਚਕਾਰ ਹਰ ਕੰਪੋਨੈਂਟ ਇੱਕ ਕੂਰੀਅਰ ਬਣ ਜਾਂਦਾ ਹੈ। ਐਪ ਤਾਂ ਚੱਲਦੀ ਰਹਿੰਦੀ ਹੈ, ਪਰ codebase ਨਾਜ਼ੁਕ ਹੋ ਜਾਂਦਾ ਹੈ। ਇੱਕ ਵਿਚਕਾਰਲੀ ਪਰਤ ਹਟਾਓ, ਅਤੇ ਅੱਧਾ tree ਟੁੱਟ ਜਾਂਦਾ ਹੈ। ਇੱਕ type ਬਦਲੋ, ਅਤੇ TypeScript ਤਿੰਨ ਡਾਇਰੈਕਟਰੀਆਂ ਵਿੱਚ ਸ਼ਿਕਾਇਤ ਕਰਨ ਲੱਗ ਪੈਂਦਾ ਹੈ। React Context API ਇਹਨਾਂ ਵਿਚੋਲਿਆਂ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਹਟਾਉਣ ਲਈ ਮੌਜੂਦ ਹੈ।

Prop Drilling ਅਸਲ ਵਿੱਚ ਕਿਹੋ ਜਿਹੀ ਦਿਖਦੀ ਹੈ

ਇੱਕ ਸਟੈਂਡਰਡ ਐਪ ਸ਼ੈੱਲ ਦੀ ਕਲਪਨਾ ਕਰੋ। ਤੁਹਾਡੇ ਕੋਲ ਇੱਕ App ਕੰਪੋਨੈਂਟ ਹੈ ਜੋ ਮੌਜੂਦਾ ਯੂਜ਼ਰ ਨੂੰ fetch ਕਰਦਾ ਹੈ। App ਦੇ ਅੰਦਰ ਇੱਕ Layout ਹੈ, Layout ਦੇ ਅੰਦਰ ਇੱਕ Sidebar ਹੈ, Sidebar ਦੇ ਅੰਦਰ ਇੱਕ Navigation ਹੈ, ਅਤੇ ਅੰਤ ਵਿੱਚ Navigation ਦੇ ਅੰਦਰ ਤੁਹਾਨੂੰ UserAvatar ਮਿਲਦਾ ਹੈ ਜਿਸਨੂੰ ਅਸਲ ਵਿੱਚ user object ਦੀ ਲੋੜ ਹੈ।

ਤੁਹਾਡਾ ਕੋਡ ਇਸ ਤਰ੍ਹਾਂ ਦਾ ਹੋ ਜਾਂਦਾ ਹੈ:

function App() {
  const user = { name: 'Aarav', role: 'admin' };
  return <Layout user={user} />;
}

function Layout({ user }) {
  return <Sidebar user={user} />;
}

function Sidebar({ user }) {
  return <Navigation user={user} />;
}

function Navigation({ user }) {
  return <UserAvatar user={user} />;
}

Layout, Sidebar, ਅਤੇ Navigation ਉਸ user object ਨਾਲ ਕੁਝ ਨਹੀਂ ਕਰਦੇ ਸਿਵਾਏ ਇਸ ਦੇ ਕਿ ਉਹ ਉਸਨੂੰ ਅੱਗੇ ਭੇਜ ਦਿੰਦੇ ਹਨ। ਉਹ ਅਜਿਹੇ props ਇਕੱਠੇ ਕਰਦੇ ਰਹਿੰਦੇ ਹਨ ਜੋ ਉਹਨਾਂ ਦੇ ਨਹੀਂ ਹਨ, ਉਹਨਾਂ ਦੇ interfaces ਵਧਦੇ ਜਾਂਦੇ ਹਨ, ਅਤੇ ਉਹਨਾਂ ਦੀ testing ਲਈ ਅਜਿਹਾ data mock ਕਰਨਾ ਪੈਂਦਾ ਹੈ ਜਿਸਨੂੰ ਉਹ ਕਦੇ ਛੂਹਦੇ ਵੀ ਨਹੀਂ। ਅਸਲੀ ਸਮੱਸਿਆ ਇਹ ਹੈ ਕਿ ਇਹ ਕਿੰਨੀ ਤੇਜ਼ੀ ਨਾਲ ਫੈਲਦਾ ਹੈ। ਇੱਕ isLoggedIn flag, ਇੱਕ locale string, ਜਾਂ ਇੱਕ theme value ਜੋੜੋ, ਅਤੇ ਉਹੀ ਪ੍ਰਕਿਰਿਆ ਦੁਬਾਰਾ ਦੁਹਰਾਈ ਜਾਂਦੀ ਹੈ।

Context API ਖੇਡ ਨੂੰ ਕਿਵੇਂ ਬਦਲ ਦਿੰਦੀ ਹੈ

Context API ਨੂੰ ਇੱਕ WiFi ਰਾਊਟਰ ਵਾਂਗ ਸਮਝੋ। ਹਰ ਡਿਵਾਈਸ ਤੱਕ ਪਹੁੰਚਣ ਲਈ ਹਰ ਕਮਰੇ ਵਿੱਚੋਂ ਲੰਬੀਆਂ ਕੇਬਲਾਂ ਲਗਾਉਣ ਦੀ ਬਜਾਏ, ਰਾਊਟਰ ਹਵਾ ਰਾਹੀਂ ਸਿਗਨਲ ਭੇਜਦਾ ਹੈ। ਰੇਂਜ ਵਿੱਚ ਕੋਈ ਵੀ ਡਿਵਾਈਸ ਸਿੱਧਾ ਕਨੈਕਟ ਹੋ ਸਕਦੀ ਹੈ। React ਦੀ ਭਾਸ਼ਾ ਵਿੱਚ, ਰਾਊਟਰ Provider ਹੈ, ਸਿਗਨਲ ਤੁਹਾਡਾ state ਜਾਂ data ਹੈ, ਅਤੇ ਡਿਵਾਈਸ ਕੋਈ ਵੀ nested component ਹੈ ਜੋ useContext ਨੂੰ ਕਾਲ ਕਰਦਾ ਹੈ।

ਇਸ ਸੈੱਟਅੱਪ ਦੇ ਤਿੰਨ ਹਿੱਸੇ ਹਨ:

  • React.createContext() ਡੇਟਾ ਚੈਨਲ ਬਣਾਉਂਦਾ ਹੈ।
  • Provider ਤੁਹਾਡੇ tree ਦੇ ਇੱਕ ਹਿੱਸੇ ਨੂੰ wrap ਕਰਦਾ ਹੈ ਅਤੇ ਇੱਕ value ਪ੍ਰਮਾਣਿਤ (transmit) ਕਰਦਾ ਹੈ।
  • useContext hook ਹੇਠਲੇ ਕੰਪੋਨੈਂਟਸ (descendants) ਨੂੰ ਵਿਚਕਾਰਲੇ props ਨੂੰ ਛੇੜੇ ਬਿਨਾਂ ਉਹ value ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ।

ਤੁਹਾਡੇ ਕੋਲ ਅਜੇ ਵੀ ਇੱਕ tree ਹੈ, ਪਰ root ਅਤੇ leaf ਦੇ ਵਿਚਕਾਰਲੀਆਂ ਟਾਹਣੀਆਂ ਨੂੰ ਹੁਣ ਕਿਸੇ ਕੂਰੀਅਰ ਕੰਟਰੈਕਟ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।

ਜ਼ੀਰੋ ਤੋਂ Context ਬਣਾਉਣਾ

ਆਓ theme settings ਦੇ ਨਾਲ ਇੱਕ ਅਸਲੀ ਉਦਾਹਰਣ ਬਣਾਈਏ, ਕਿਉਂਕਿ ਜ਼ਿਆਦਾਤਰ ਐਪਸ ਨੂੰ ਕਿਸੇ ਨਾ ਕਿਸੇ ਸਮੇਂ light ਜਾਂ dark mode ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।

ਪਹਿਲਾਂ, context object ਬਣਾਓ। ਇਹ ਪਾਈਪ ਹੈ:

import { createContext, useState, useMemo } from 'react';

const ThemeContext = createContext(null);

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

export default ThemeContext;

ਫਿਰ ਆਪਣੀ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ provider ਵਿੱਚ wrap ਕਰੋ। ਆਮ ਤੌਰ 'ਤੇ ਇਹ root ਦੇ ਨੇੜੇ ਹੁੰਦਾ ਹੈ:

import { ThemeProvider } from './ThemeContext';

function App() {
  return (
    <ThemeProvider>
      <Layout />
    </ThemeProvider>
  );
}

ਹੁਣ ਕੋਈ ਵੀ descendant ਸਿੱਧਾ ਸਿਗਨਲ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦਾ ਹੈ। ਇੱਥੇ UI ਦੇ ਬਹੁਤ ਅੰਦਰ ਇੱਕ toggle button ਹੈ:

import { useContext } from 'react';
import ThemeContext from './ThemeContext';

function ThemeToggle() {
  const { theme, setTheme } = useContext(ThemeContext);

  return (
    <button
      onClick={() => setTheme(prev => prev === 'light' ? 'dark' : 'light')}
    >
      Current theme: {theme}
    </button>
  );
}

ਨੋਟ ਕਰੋ ਕਿ Layout, Sidebar, ਅਤੇ Navigation ਕਦੇ ਵੀ theme prop ਨੂੰ ਨਹੀਂ ਦੇਖਦੇ। ਉਹ ਆਮ ਤੌਰ 'ਤੇ render ਹੁੰਦੇ ਹਨ, ਅਤੇ ThemeToggle ਸਿੱਧਾ context ਤੋਂ ਉਹ ਲੈਂਦਾ ਹੈ ਜਿਸਦੀ ਉਸਨੂੰ ਲੋੜ ਹੈ। ਵਾਇਰਿੰਗ ਬਾਹਰੋਂ ਅਦਿੱਖ ਹੈ, ਜੋ ਕਿ ਅਸਲ ਵਿੱਚ ਇਸਦਾ ਮਕਸਦ ਹੈ।

Context ਅਸਲ ਵਿੱਚ ਕਿੱਥੇ ਫਿੱਟ ਬੈਠਦਾ ਹੈ

Context ਉਸ ਡੇਟਾ ਲਈ ਸਭ ਤੋਂ ਵਧੀਆ ਕੰਮ ਕਰਦਾ ਹੈ ਜੋ ਬਹੁਤ ਸਾਰੇ ਦੂਰ-ਦੁਰਾਡੇ ਦੇ ਕੰਪੋਨੈਂਟਸ ਸਾਂਝੇ ਕਰਦੇ ਹਨ ਪਰ ਕੋਈ ਵੀ ਇੱਕ parent ਉਸਦਾ ਮਾਲਕ ਨਹੀਂ ਹੁੰਦਾ। ਵਧੀਆ ਉਦਾਹਰਣਾਂ ਵਿੱਚ ਸ਼ਾਮਲ ਹਨ:

  • Theme settings ਜਿਵੇਂ ਕਿ light ਜਾਂ dark mode, accent colors, ਜਾਂ font scaling।
  • Authentication state ਜਿਵੇਂ ਕਿ ਮੌਜੂਦਾ user object, login status, ਜਾਂ session expiry।
  • Language and locale ਸੈਟਿੰਗਜ਼ internationalization ਲਈ।
  • Shopping cart data ਜੋ header badge, ਇੱਕ mini-cart dropdown, ਅਤੇ checkout page ਵਿੱਚ ਸਿੰਕ (sync) ਰਹਿਣਾ ਚਾਹੀਦਾ ਹੈ।

ਹਰ ਇੱਕ local state ਨੂੰ Context ਵਿੱਚ ਪਾਉਣ ਦੀ ਇੱਛਾ ਤੋਂ ਬਚੋ। ਦੋ ਪੱਧਰ ਹੇਠਾਂ ਵਾਲੇ form input ਨੂੰ global broadcast ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ। Context ਨੂੰ ਅਸਲੀ cross-cutting ਚੀਜ਼ਾਂ ਲਈ ਰੱਖੋ, ਅਤੇ ਬਾਕੀ ਨੂੰ ਆਮ props ਵਜੋਂ ਰਹਿਣ ਦਿਓ।

ਪਰਫਾਰਮੈਂਸ ਦੇ ਜਾਲ ਅਤੇ ਉਹਨਾਂ ਤੋਂ ਕਿਵੇਂ ਬਚਣਾ ਹੈ

Context ਮੁਫ਼ਤ ਨਹੀਂ ਹੈ। ਜਦੋਂ ਕੋਈ context value ਅਪਡੇਟ ਹੁੰਦੀ ਹੈ, ਤਾਂ ਹਰ ਉਹ ਕੰਪੋਨੈਂਟ ਜੋ ਉਸ context ਨਾਲ ਜੁੜਿਆ ਹੋਇਆ ਹੈ, re-render ਹੁੰਦਾ ਹੈ, ਭਾਵੇਂ ਉਹ value ਜਿਸਦੀ ਉਹਨਾਂ ਨੂੰ ਪਰਵਾਹ ਹੈ, ਬਦਲੀ ਨਾ ਹੋਵੇ। ਸਭ ਤੋਂ ਵੱਡੀ ਗਲਤੀ ਹਰ parent render 'ਤੇ Provider ਵਿੱਚ ਇੱਕ ਨਵਾਂ object literal ਪਾਉਣਾ ਹੈ।

ਸਾਡੀ theme ਉਦਾਹਰਣ ਵਿੱਚ, ਹਰ ਵਾਰ ਜਦੋਂ ThemeProvider re-render ਹੁੰਦਾ ਹੈ ਕਿਉਂਕਿ ਉਸਦਾ ਆਪਣਾ parent ਅਪਡੇਟ ਹੋਇਆ ਹੈ, ਤਾਂ { theme, setTheme } ਦਾ expression ਇੱਕ ਬਿਲਕੁਲ ਨਵਾਂ object ਬਣਾਉਂਦਾ ਹੈ। React ਇੱਕ ਨਵਾਂ reference ਦੇਖਦਾ ਹੈ, ਅਤੇ ਹਰ consumer ਅਪਡੇਟ ਹੋ ਜਾਂਦਾ ਹੈ। ਜੇਕਰ ਤੁਹਾਡੀ theme ਬਹੁਤ ਘੱਟ ਬਦਲਦੀ ਹੈ ਪਰ ਤੁਹਾਡੀ app state ਅਕਸਰ ਬਦਲਦੀ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਉਹਨਾਂ renders ਲਈ ਕੀਮਤ ਚੁੱਕ ਰਹੇ ਹੋ ਜਿਨ੍ਹਾਂ ਦੀ ਤੁਹਾਨੂੰ ਲੋੜ ਨਹੀਂ ਹੈ।

ਇਸਦਾ ਹੱਲ ਦੋਹਰਾ ਹੈ।

ਆਪਣੇ contexts ਨੂੰ ਅਪਡੇਟ ਦੀ ਬਾਰੰਬਾਰਤਾ (frequency) ਅਨੁਸਾਰ ਵੱਖ ਕਰੋ। ਇੱਕ UserContext ਜੋ ਪ੍ਰਤੀ login ਇੱਕ ਵਾਰ ਬਦਲਦਾ ਹੈ, ਉਸਨੂੰ NotificationContext ਦੇ ਨਾਲ ਇੱਕੋ provider ਸਾਂਝਾ ਨਹੀਂ ਕਰਨਾ ਚਾਹੀਦਾ ਜੋ ਹਰ ਕੁਝ ਸਕਿੰਟਾਂ ਵਿੱਚ ਅਪਡੇਟ ਹੁੰਦਾ ਹੈ। ਉਹਨਾਂ ਨੂੰ ਵੱਖ ਰੱਖੋ ਤਾਂ ਜੋ static data ਉਸੇ re-render ਟ੍ਰੇਨ ਵਿੱਚ ਨਾ ਚੱਲੇ ਜਿਸ ਵਿੱਚ volatile data ਚੱਲ ਰਿਹਾ ਹੈ।

ਜਦੋਂ value ਇੱਕ object ਜਾਂ array ਹੋਵੇ ਤਾਂ ਉਸਨੂੰ useMemo ਵਿੱਚ wrap ਕਰੋ। React ਨੂੰ ਇੱਕ ਸਥਿਰ (stable) reference ਦਿਓ:

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  const value = useMemo(() => ({ theme, setTheme }), [theme]);

  return (
    <ThemeContext.Provider value={value}>
      {children}
    </ThemeContext.Provider>
  );
}

ਹੁਣ ਆਬਜੈਕਟ ਦੀ ਪਛਾਣ (object identity) ਉਦੋਂ ਹੀ ਬਦਲਦੀ ਹੈ ਜਦੋਂ theme ਅਸਲ ਵਿੱਚ ਬਦਲਦਾ ਹੈ। ਹੇਠਲੇ ਪੱਧਰ 'ਤੇ ਮੌਜੂਦ ਉਹ ਡੈਸੈਂਡੈਂਟ ਕੰਪੋਨੈਂਟਸ ਜੋ ਕੰਟੈਕਸ (context) ਬਾਰੇ ਜਾਣਕਾਰੀ ਰੱਖਦੇ ਹਨ ਪਰ React.memo ਦੁਆਰਾ ਸੁਰੱਖਿਅਤ ਹਨ, ਉਹ ਇਸ ਕੰਮ ਨੂੰ ਕਰਨ ਤੋਂ ਬਚ ਜਾਣਗੇ।

ਉਹ ਗਲਤੀਆਂ ਜੋ ਤੁਹਾਡਾ ਸਮਾਂ ਬਰਬਾਦ ਕਰਦੀਆਂ ਹਨ

ਉਹ ਦੋ ਗਲਤੀਆਂ ਜੋ ਅਜੇ ਵੀ ਪ੍ਰੋਡਕਸ਼ਨ ਕੋਡ ਵਿੱਚ ਦਿਖਾਈ ਦਿੰਦੀਆਂ ਹਨ, ਉਹਨਾਂ ਤੋਂ ਬਚਣਾ ਆਸਾਨ ਹੈ।

ਪਹਿਲੀ ਗਲਤੀ, ਖੁਦ ਕੰਟੈਕਸ (context) ਨੂੰ ਐਕਸਪੋਰਟ (export) ਕਰਨਾ ਭੁੱਲ ਜਾਣਾ। ਜੇਕਰ ਤੁਸੀਂ ਸਿਰਫ਼ Provider wrapper ਨੂੰ ਐਕਸਪੋਰਟ ਕਰਦੇ ਹੋ ਅਤੇ context ਆਬਜੈਕਟ ਨੂੰ ਪ੍ਰਾਈਵੇਟ ਰੱਖਦੇ ਹੋ, ਤਾਂ ਇੱਕ ਨਵਾਂ ਫੀਚਰ ਲਿਖਣ ਵਾਲਾ ਡਿਵੈਲਪਰ ਤੁਹਾਡੇ ਮੋਡਿਊਲ ਨੂੰ ਰੀਫੈਕਟਰ (refactoring) ਕੀਤੇ ਬਿਨਾਂ useContext ਨੂੰ ਕਾਲ ਨਹੀਂ ਕਰ ਸਕਦਾ। ਕੰਟੈਕਸ ਨੂੰ ਐਕਸਪੋਰਟ ਕਰੋ ਤਾਂ ਜੋ ਕੰਜ਼ਿਊਮਰਜ਼ (consumers) ਪ੍ਰੋਵਾਈਡਰ ਅਤੇ ਕੰਜ਼ਿਊਮਰ ਹੁੱਕ (consumer hook) ਦੋਵਾਂ ਨੂੰ ਸਾਫ਼ ਤਰੀਕੇ ਨਾਲ ਇੰਪੋਰਟ ਕਰ ਸਕਣ।

ਦੂਜੀ ਗਲਤੀ, ਸੰਬੰਧਿਤ Provider ਤੋਂ ਬਾਹਰ useContext ਨੂੰ ਕਾਲ ਕਰਨਾ। ਜੇਕਰ ThemeToggle ਟ੍ਰੀ (tree) ਦੀ ਕਿਸੇ ਅਜਿਹੀ ਸ਼ਾਖਾ (branch) ਵਿੱਚ ਰੈਂਡਰ ਹੁੰਦਾ ਹੈ ਜੋ ThemeProvider ਵਿੱਚ ਲਪੇਟਿਆ (wrapped) ਨਹੀਂ ਹੈ, ਤਾਂ ਹੁੱਕ createContext ਨੂੰ ਦਿੱਤੀ ਗਈ ਡਿਫੌਲਟ ਵੈਲਯੂ (default value) ਵਾਪਸ ਕਰਦਾ ਹੈ, ਜਾਂ ਜੇਕਰ ਤੁਸੀਂ ਕੁਝ ਨਹੀਂ ਦਿੱਤਾ ਹੈ ਤਾਂ undefined ਵਾਪਸ ਕਰਦਾ ਹੈ। ਇਸ ਨਾਲ cannot read property of undefined ਵਰਗੀਆਂ ਚੁੱਪਚਾਪ ਹੋਣ ਵਾਲੀਆਂ ਗਲਤੀਆਂ (silent failures) ਹੋ ਸਕਦੀਆਂ ਹਨ। ਤੁਸੀਂ ਇੱਕ ਉਚਿਤ ਡਿਫੌਲਟ ਮੁੱਲ ਨਿਰਧਾਰਤ ਕਰਕੇ ਜਾਂ ਹੁੱਕ ਕਾਲ ਦੇ ਸ਼ੁਰੂ ਵਿੱਚ ਹੀ ਇੱਕ ਸਪਸ਼ਟ ਐਰਰ (error) ਦਿਖਾ ਕੇ ਇਸ ਤੋਂ ਬਚ ਸਕਦੇ ਹੋ।

Context ਬਨਾਮ Redux: ਇਸਨੂੰ ਸਰਲ ਰੱਖੋ

ਤੁਹਾਨੂੰ ਹਮੇਸ਼ਾ Redux ਦੀ ਲੋੜ ਨਹੀਂ ਹੁੰਦੀ। ਦਰਮਿਆਨੇ ਆਕਾਰ ਦੇ ਪ੍ਰੋਜੈਕਟਾਂ ਲਈ, useState ਜਾਂ useReducer ਦੇ ਨਾਲ Context ਸਟੇਟ ਸ਼ੇਅਰਿੰਗ (state sharing) ਦਾ ਜ਼ਿਆਦਾਤਰ ਹਿੱਸਾ ਸੰਭਾਲ ਲੈਂਦਾ ਹੈ। Redux ਉਦੋਂ ਫਾਇਦੇਮੰਦ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਤੁਹਾਨੂੰ time-travel debugging, ਗੁੰਝਲਦਾਰ middleware, ਜਾਂ ਗਲੋਬਲ ਟ੍ਰਾਂਜੈਕਸ਼ਨਾਂ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ ਜੋ ਕ੍ਰਮਵਾਰ ਰੋਲ ਬੈਕ (roll back) ਹੋਣੀਆਂ ਚਾਹੀਦੀਆਂ ਹਨ। ਜੇਕਰ ਤੁਹਾਡੀ ਪੂਰੀ ਸਟੇਟ (state) ਸਿਰਫ਼ ਇੱਕ user object, ਇੱਕ theme string, ਅਤੇ ਇੱਕ cart array ਹੈ, ਤਾਂ ਇੱਕ store library ਵਾਧੂ ਬੋਇਲਰਪਲੇਟ (boilerplate) ਜੋੜ ਦਿੰਦੀ ਹੈ ਜਿਸਦਾ ਤੁਸੀਂ ਕਦੇ ਵੀ ਇਸਤੇਮਾਲ ਨਹੀਂ ਕਰੋਗੇ।

ਫਿਰ ਵੀ, Context ਆਪਣੇ ਆਪ ਵਿੱਚ ਇੱਕ ਪੂਰਾ ਸਟੇਟ ਮੈਨੇਜਮੈਂਟ ਸਿਸਟਮ (state management system) ਨਹੀਂ ਹੈ। ਇਹ ਤੁਹਾਨੂੰ ਇੱਕ ਸਿੰਗਲ ਗਲੋਬਲ ਸਨੈਪਸ਼ਾਟ (global snapshot) ਨਹੀਂ ਦਿੰਦਾ, ਅਤੇ ਇਹ ਅਸੰਬੰਧਿਤ ਕੰਟੈਕਸਾਂ ਵਿੱਚ ਅੱਪਡੇਟਸ ਨੂੰ ਬੈਚ (batch) ਨਹੀਂ ਕਰਦਾ। ਇਸਦੀ ਵਰਤੋਂ prop drilling ਦੇ ਬਦਲ ਵਜੋਂ ਕਰੋ, ਨਾ ਕਿ ਆਪਣੇ ਪੂਰੇ ਡੇਟਾ ਲੇਅਰ (data layer) ਲਈ ਇੱਕ ਓਪਰੇਟਿੰਗ ਸਿਸਟਮ ਵਜੋਂ।

ਅਸਲ ਸਿੱਖਿਆ

ਉਹਨਾਂ ਕੰਪੋਨੈਂਟਸ ਰਾਹੀਂ props ਨੂੰ ਪਾਸ ਕਰਨਾ ਬੰਦ ਕਰੋ ਜਿਨ੍ਹਾਂ ਨੂੰ ਉਹਨਾਂ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ। ਉਸ ਡੇਟਾ ਲਈ ਫੋਕਸਡ ਕੰਟੈਕਸ (focused contexts) ਬਣਾਓ ਜੋ ਅਸਲ ਵਿੱਚ ਤੁਹਾਡੇ ਟ੍ਰੀ (tree) ਵਿੱਚ ਫੈਲਿਆ ਹੋਇਆ ਹੈ, ਕੰਜ਼ਿਊਮਰਜ਼ ਨੂੰ ਕਵਰ ਕਰਨ ਲਈ ਪ੍ਰੋਵਾਈਡਰਾਂ ਨੂੰ ਉੱਚੇ ਪੱਧਰ 'ਤੇ ਰੱਖੋ, ਅਤੇ ਜਦੋਂ ਤੁਸੀਂ ਕਲੈਕਸ਼ਨਾਂ (collections) ਜਾਂ ਫੰਕਸ਼ਨਾਂ (functions) ਨੂੰ ਪਾਸ ਕਰ ਰਹੇ ਹੋ ਤਾਂ ਹਮੇਸ਼ਾ value object ਨੂੰ ਸਥਿਰ (stabilize) ਰੱਖੋ। Context API ਤੁਹਾਡੇ React ਕੋਡ ਨੂੰ ਸਿੱਧਾ ਰੱਖਦੀ ਹੈ: props ਸਥਾਨਕ (local) ਰਹਿੰਦੇ ਹਨ, ਗਲੋਬਲ ਡੇਟਾ ਬਿਨਾਂ ਕਿਸੇ ਰੁਕਾਵਟ ਦੇ ਸਫ਼ਰ ਕਰਦਾ ਹੈ, ਅਤੇ ਤੁਹਾਡੀਆਂ ਕੰਪੋਨੈਂਟ ਸੀਮਾਵਾਂ (component boundaries) ਸਾਫ਼ ਰਹਿੰਦੀਆਂ ਹਨ।