React 18 એ useSyncExternalStore ઉમેર્યું છે, જે એક એવું hook છે જે components ને React tree ની બહાર રહેલા કોઈપણ source (જેમ કે browser APIs, WebSockets, અથવા third-party stores) માંથી ડેટા વાંચવાની મંજૂરી આપે છે—તે પણ useState અને useEffect દ્વારા ડેટાને mirror કરવાની જૂની પદ્ધતિમાં જોવા મળતી visual glitches વગર. જો તમે ક્યારેય UI માં ફ્લિકર (flicker) જોયું હોય કારણ કે તેનો એક ભાગ જૂનું window size બતાવતો હતો જ્યારે બીજો ભાગ પહેલેથી જ નવું size બતાવી રહ્યો હતો, તો આ hook એ સમાધાન છે જેની તમે રાહ જોઈ રહ્યા હતા.

શા માટે external state ને નવા hook ની જરૂર છે

React components હંમેશા તેમની પોતાની scope ની બહાર રહેલી વસ્તુઓને subscribe કરવા માટે સક્ષમ રહ્યા છે: જેમ કે window object, Redux store, અથવા WebSocket connection. પરંપરાગત અભિગમ useEffect ની અંદર subscription સેટઅપ કરવાનો, setState દ્વારા આવતા values ને local state માં મોકલવાનો અને React ને re-render કરવા દેવાનો હતો. જ્યારે React synchronously render કરે છે ત્યારે આ બરાબર કામ કરે છે, પરંતુ React 18 એ concurrent rendering રજૂ કરી છે, જ્યાં browser ખરેખર paint કરે તે પહેલાં એક component ને અનેક વખત render કરવામાં આવી શકે છે. આ mode માં “mirror-into-local-state” પેટર્ન tearing પેદા કરી શકે છે—એટલે કે એક જ render cycle દરમિયાન UI ના અલગ-અલગ ભાગો એક જ external value ના અલગ-અલગ snapshots વાંચે છે.

useSyncExternalStore ને tearing રોકવા માટે બનાવવામાં આવ્યું છે. તે external source પાસેથી a snapshot (વર્તમાન value) અને a subscribe function (ફેરફારો વિશે કેવી રીતે જાણ કરવી) માંગે છે. જ્યારે component mount થાય છે ત્યારે React subscribe ને કોલ કરે છે અને unmount થતી વખતે આપમેળે unsubscribe કરી દે છે. જ્યારે પણ getSnapshot દ્વારા return કરવામાં આવેલ snapshot બદલાય છે, ત્યારે React એક એવું render schedule કરે છે જે આખા component tree માટે એ જ snapshot વાંચે છે, જે consistency ની ખાતરી આપે છે.

બે જરૂરી functions

Function તે શું કરે છે
subscribe એક callback મેળવે છે જેને external value બદલાય ત્યારે કોલ કરવો જ જોઈએ. તે એક unsubscribe function return કરે છે જેને React cleanup વખતે કોલ કરશે.
getSnapshot external source માંથી વર્તમાન value return કરે છે. તે referentially stable હોવું જોઈએ—દરેક render વખતે સમાન function object—જેથી React snapshots ને યોગ્ય રીતે સરખાવી શકે.

Browser ના online status માટે એક minimal implementation આ મુજબ દેખાય છે:

function useOnlineStatus() {
  return useSyncExternalStore(
    (onChange) => {
      window.addEventListener('online', onChange);
      window.addEventListener('offline', onChange);
      return () => {
        window.removeEventListener('online', onChange);
        window.removeEventListener('offline', onChange);
      };
    },
    () => navigator.onLine
  );
}

જ્યારે પણ કોઈ component useOnlineStatus() ને કોલ કરે છે, ત્યારે React તેને ત્યારે જ re-render કરશે જ્યારે navigator.onLine ખરેખર બદલાશે, અને દરેક render માં એક જ value જોવા મળશે.

એવા નિયમો જે hook ને બગડતા અટકાવે છે

  1. Component ને જરૂરી હોય તેટલો જ નાનો ડેટા return કરો.
    જો external store માં મોટું object હોય પરંતુ component ને માત્ર એક જ field ની જરૂર હોય, તો ફક્ત તે જ field return કરો. મોટું return કરવાથી બિનજરૂરી renders થાય છે.

  2. getSnapshot ને memoise કરો.
    જો તમે દરેક render પર function ને ફરીથી બનાવો છો, તો React તેને નવો source માની લેશે અને તે અનંત લૂપ (infinite loop) માં ફસાઈ શકે છે. તેને useCallback માં wrap કરો અથવા component ની બહાર define કરો.

  3. દરેક call પર નવા objects return કરવાનું ટાળો.
    નવું object return કરવાથી (દા.ત., { count: store.getCount() }) દરેક render પર એક નવો reference બને છે, જેનાથી React ને લાગે છે કે snapshot બદલાઈ ગયો છે અને તે infinite render loop શરૂ કરી દે છે. Primitives, strings, numbers, અથવા memoised objects નો ઉપયોગ કરો.

  4. તેનો ઉપયોગ internal component state માટે ન કરો.
    જે ડેટા માત્ર component ની અંદર રહે છે તેના માટે useState હજુ પણ સાચું સાધન છે. useSyncExternalStore વધારાનો overhead ઉમેરે છે જે local state માટે જરૂરી નથી.

તેનો ઉપયોગ ક્યારે કરવો

  • Browser APIs – window size, media queries, navigator.onLine, battery status.
  • Framework-agnostic stores – Zustand, Redux, MobX, અથવા કોઈપણ custom store જે subscription API પ્રદાન કરે છે.
  • Mutable sources જે React ની બહાર update થાય છે – WebSocket messages, IndexedDB change events, Service Worker notifications.

જો તમારો data source પહેલેથી જ React ની અંદર હોય (દા.ત., parent component ની state), તો useState અથવા context નો જ ઉપયોગ કરો.

કોમ્યુનિટી શું કહી રહી છે

શરૂઆતના વપરાશકર્તાઓ જણાવે છે કે useSyncExternalStore થી concurrent-rendering setup માં window resize કરતી વખતે જોવા મળતું flicker દૂર થાય છે. કેટલીક libraries એ પહેલેથી જ તેમના internal hooks ને આ API માં બદલી નાખ્યા છે, જે React ના વિવિધ versions માં વધુ અનુમાનિત (predictable) વર્તનની ખાતરી આપે છે. આનો trade-off એ થોડો વધુ માનસિક ભાર (mental load) છે: developers એ બંને functions ની stability વિશે વિચારવું પડશે અને દરેક call પર નવા objects return કરવાનું ટાળવું પડશે.

આગળ શું જોવું

React ના આગામી રિલીઝ useSyncExternalStore ની આસપાસના કરારને વધુ મજબૂત બનાવી શકે છે, જે કદાચ સામાન્ય બ્રાઉઝર APIs માટે ઇન-બિલ્ટ હેલ્પર્સ ઉમેરી શકે છે. જૂના useEffect-mirroring પેટર્નના કોઈપણ ડિપ્રિકેશન (deprecations) માટે સત્તાવાર React બ્લોગ પર નજર રાખો. તે દરમિયાન, આ હૂક સ્થિર છે અને પબ્લિક API નો ભાગ છે, તેથી તમે હાલના એક્સટર્નલ-સ્ટેટ કોડને સુરક્ષિત રીતે રિફેક્ટર કરી શકો છો.

ઝડપી ટેસ્ટ ડ્રાઇવ

એક લાઈવ ડેમો જે વિન્ડો-સાઇઝ સિંકિંગ, ઓનલાઇન/ઓફલાઇન ડિટેક્શન અને એક સરળ Zustand સ્ટોર દર્શાવે છે, તે https://usesyncexternalstore.vercel.app/ પર ઉપલબ્ધ છે. કોમેન્ટ્સ સાથેનો સોર્સ કોડ https://github.com/dev48v/usesyncexternalstore પર ઉપલબ્ધ છે.

મુખ્ય વાત: useSyncExternalStore React ને તેના રેન્ડર સાયકલની બહાર રહેતા કોઈપણ મ્યુટેબલ ડેટા માટે એક વિશ્વસનીય બ્રિજ આપે છે, જે tearing અને બિનજરૂરી રેન્ડર્સને અટકાવે છે. તેને એક્સટર્નલ સોર્સ પર લાગુ કરો, સ્નેપશોટને ન્યૂનતમ અને સ્થિર રાખો, અને સુસંગતતા (consistency) જાળવવાનું મુખ્ય કામ React ને કરવા દો.