Skip to content

સસ્પેન્સ (Suspense)

પ્રાયોગિક સુવિધા (Experimental Feature)

<Suspense> એ એક પ્રાયોગિક સુવિધા છે. તે સ્ટેબલ સ્ટેટસ સુધી પહોંચશે તેની કોઈ ગેરંટી નથી અને તે થાય તે પહેલા API બદલાઈ શકે છે.

<Suspense> એ કમ્પોનન્ટ ટ્રીમાં એસિંક ડિપેન્ડન્સીસને ઓર્કેસ્ટ્રેટ કરવા માટેનું બિલ્ટ-ઇન ઘટક છે. તે કમ્પોનન્ટ ટ્રીમાં બહુવિધ નેસ્ટેડ એસિંક ડિપેન્ડન્સીસ રિઝોલ્વ થવાની રાહ જોતી વખતે લોડિંગ સ્ટેટ રેન્ડર કરી શકે છે.

એસિંક ડિપેન્ડન્સીસ (Async Dependencies)

<Suspense> જે સમસ્યા હલ કરવાનો પ્રયાસ કરી રહ્યું છે અને તે આ એસિંક ડિપેન્ડન્સીસ સાથે કેવી રીતે ક્રિયાપ્રતિક્રિયા કરે છે તે સમજાવવા માટે, ચાલો નીચે મુજબના કમ્પોનન્ટ વંશવેલો (hierarchy) ની કલ્પના કરીએ:

<Suspense>
└─ <Dashboard>
   ├─ <Profile>
   │  └─ <FriendStatus> (એસિંક setup() વાળો ઘટક)
   └─ <Content>
      ├─ <ActivityFeed> (એસિંક ઘટક)
      └─ <Stats> (એસિંક ઘટક)

કમ્પોનન્ટ ટ્રીમાં બહુવિધ નેસ્ટેડ ઘટકો છે જેનું રેન્ડરિંગ કેટલીક એસિંક રિસોર્સ પર આધાર રાખે છે જે પહેલાથી રિઝોલ્વ થવા જોઈએ. <Suspense> વિના, તેમાંના દરેકે પોતાના લોડિંગ / એરર અને લોડેડ સ્ટેટ્સને હેન્ડલ કરવાની જરૂર પડશે. સૌથી ખરાબ પરિસ્થિતિમાં, આપણે પેજ પર ત્રણ લોડિંગ સ્પિનર્સ જોઈ શકીએ છીએ, જેમાં વિવિધ સમયે કન્ટેન્ટ પ્રદર્શિત થાય છે.

<Suspense> ઘટક આપણને ટોપ-લેવલ લોડિંગ / એરર સ્ટેટ્સ પ્રદર્શિત કરવાની ક્ષમતા આપે છે જ્યારે આપણે આ નેસ્ટેડ એસિંક ડિપેન્ડન્સીસ રિઝોલ્વ થવાની રાહ જોતા હોઈએ.

ત્યાં બે પ્રકારની એસિંક ડિપેન્ડન્સીસ છે જેના પર <Suspense> રાહ જોઈ શકે છે:

૧. એસિંક setup() હૂક ધરાવતા ઘટકો. આમાં ટોપ-લેવલ await એક્સપ્રેશન સાથે <script setup> નો ઉપયોગ કરતા ઘટકોનો સમાવેશ થાય છે.

૨. એસિંક કમ્પોનન્ટ્સ.

એસિંક (async) setup()

Composition API ઘટકનું setup() હૂક એસિંક હોઈ શકે છે:

js
export default {
  async setup() {
    const res = await fetch(...)
    const posts = await res.json()
    return {
      posts
    }
  }
}

જો <script setup> નો ઉપયોગ કરી રહ્યાં હોવ, તો ટોપ-લેવલ await એક્સપ્રેશનની હાજરી આપમેળે ઘટકને એસિંક ડિપેન્ડન્સી બનાવે છે:

vue
<script setup>
const res = await fetch(...)
const posts = await res.json()
</script>

<template>
  {{ posts }}
</template>

એસિંક કમ્પોનન્ટ્સ (Async Components)

એસિંક ઘટકો ડિફોલ્ટ રૂપે "સસ્પેન્સિબલ (suspensible)" હોય છે. આનો અર્થ એ છે કે જો તેની પેરેન્ટ ચેઇનમાં <Suspense> હોય, તો તેને તે <Suspense> ની એસિંક ડિપેન્ડન્સી તરીકે ગણવામાં આવશે. આ કિસ્સામાં, લોડિંગ સ્ટેટને <Suspense> દ્વારા નિયંત્રિત કરવામાં આવશે, અને ઘટકના પોતાના લોડિંગ, એરર, વિલંબ અને ટાઈમઆઉટ ઓપ્શન્સને અવગણવામાં આવશે.

એસિંક કમ્પોનન્ટ તેના ઓપ્શન્સમાં suspensible: false સ્પષ્ટ કરીને Suspense કંટ્રોલમાંથી નાપસંદ (opt-out) કરી શકે છે અને કમ્પોનન્ટને હંમેશા તેની પોતાની લોડિંગ સ્ટેટ નિયંત્રિત કરવા દે છે.

લોડિંગ સ્ટેટ (Loading State)

<Suspense> ઘટકમાં બે સ્લોટ્સ છે: #default અને #fallback. બંને સ્લોટ્સ માત્ર એક તાત્કાલિક બાળ (immediate child) નોડ માટે પરવાનગી આપે છે. જો શક્ય હોય તો ડિફોલ્ટ સ્લોટમાં નોડ બતાવવામાં આવે છે. જો નહીં, તો તેના બદલે ફોલબેક સ્લોટમાં નોડ બતાવવામાં આવશે.

template
<Suspense>
  <!-- નેસ્ટેડ એસિંક ડિપેન્ડન્સીસવાળા ઘટક -->
  <Dashboard />

  <!-- #fallback સ્લોટ દ્વારા લોડિંગ સ્ટેટ -->
  <template #fallback>
    લોડ થઈ રહ્યું છે...
  </template>
</Suspense>

પ્રારંભિક રેન્ડર પર, <Suspense> મેમરીમાં તેના ડિફોલ્ટ સ્લોટ કન્ટેન્ટને રેન્ડર કરશે. જો પ્રક્રિયા દરમિયાન કોઈ એસિંક ડિપેન્ડન્સી મળે છે, તો તે પેન્ડિંગ (pending) સ્ટેટમાં પ્રવેશશે. પેન્ડિંગ સ્ટેટ દરમિયાન, ફોલબેક કન્ટેન્ટ પ્રદર્શિત કરવામાં આવશે. જ્યારે મળેલી તમામ એસિંક ડિપેન્ડન્સીસ રિઝોલ્વ થઈ જાય, ત્યારે <Suspense> રિઝોલ્વ્ડ (resolved) સ્ટેટમાં પ્રવેશે છે અને રિઝોલ્વ થયેલ ડિફોલ્ટ સ્લોટ કન્ટેન્ટ પ્રદર્શિત થાય છે.

જો પ્રારંભિક રેન્ડર દરમિયાન કોઈ એસિંક ડિપેન્ડન્સી મળી નથી, તો <Suspense> સીધું રિઝોલ્વ સ્ટેટમાં જશે.

એકવાર રિઝોલ્વ સ્ટેટમાં આવ્યા પછી, જો #default સ્લોટના રૂટ નોડને બદલવામાં આવે તો જ <Suspense> ફરીથી પેન્ડિંગ સ્ટેટમાં પાછું આવશે. ટ્રીમાં ઊંડે નેસ્ટ કરેલી નવી એસિંક ડિપેન્ડન્સીસ <Suspense> ને પેન્ડિંગ સ્ટેટમાં પાછા લાવવાનું કારણ બનશે નહીં.

જ્યારે રિવર્ટ (revert) થાય છે, ત્યારે ફોલબેક કન્ટેન્ટ તરત જ પ્રદર્શિત કરવામાં આવશે નહીં. તેના બદલે, <Suspense> નવું કન્ટેન્ટ અને તેની એસિંક ડિપેન્ડન્સીસ રિઝોલ્વ થવાની રાહ જોતી વખતે અગાઉનું #default કન્ટેન્ટ પ્રદર્શિત કરશે. આ વર્તનને timeout પ્રોપ સાથે કોન્ફિગર કરી શકાય છે: જો નવું ડિફોલ્ટ કન્ટેન્ટ રેન્ડર કરવામાં timeout મિલિસેકન્ડ્સ કરતા વધુ સમય લાગે તો <Suspense> ફોલબેક કન્ટેન્ટ પર સ્વિચ કરશે. timeout ની 0 કિંમત જ્યારે ડિફોલ્ટ કન્ટેન્ટ બદલવામાં આવે ત્યારે ફોલબેક કન્ટેન્ટ તરત જ પ્રદર્શિત કરવાનું કારણ બનશે.

ઇવેન્ટ્સ (Events)

<Suspense> ઘટક ૩ ઇવેન્ટ્સ આપે છે: pending, resolve અને fallback. pending ઇવેન્ટ જ્યારે પેન્ડિંગ સ્ટેટમાં પ્રવેશે ત્યારે થાય છે. resolve ઇવેન્ટ ત્યારે ઉત્સર્જિત થાય છે જ્યારે default સ્લોટમાં નવું કન્ટેન્ટ રિઝોલ્વ કરવાનું સમાપ્ત કરે છે. fallback ઇવેન્ટ જ્યારે fallback સ્લોટની સામગ્રી બતાવવામાં આવે ત્યારે ફાયર થાય છે.

ઇવેન્ટ્સનો ઉપયોગ કરી શકાય છે, ઉદાહરણ તરીકે, જ્યારે નવા ઘટકો લોડ થઈ રહ્યા હોય ત્યારે જૂના DOM ની સામે લોડિંગ સૂચક (loading indicator) બતાવવા માટે.

એરર હેન્ડલિંગ (Error Handling)

<Suspense> હાલમાં ઘટક દ્વારા જ એરર હેન્ડલિંગ પ્રદાન કરતું નથી - જો કે, તમે errorCaptured ઓપ્શન અથવા onErrorCaptured() હૂકનો ઉપયોગ કરી શકો છો જેથી તે <Suspense> ના પેરેન્ટ કમ્પોનન્ટમાં એસિંક એરર્સ કૅપ્ચર અને હેન્ડલ કરી શકે.

અન્ય કમ્પોનન્ટ્સ સાથે સંયોજન

ઘણીવાર <Transition> અને <KeepAlive> ઘટકો સાથે સંયોજનમાં <Suspense> નો ઉપયોગ કરવામાં આવે છે. આ ઘટકોનો નેસ્ટિંગ ઓર્ડર તે બધાને યોગ્ય રીતે કાર્ય કરવા માટે મહત્વપૂર્ણ છે.

વધારામાં, આ ઘટકોનો ઉપયોગ ઘણીવાર Vue Router ના <RouterView> ઘટક સાથે કરવામાં આવે છે.

નીચેનું ઉદાહરણ બતાવે છે કે આ ઘટકોને કેવી રીતે નેસ્ટ કરવા જોઈએ જેથી તેઓ અપેક્ષા મુજબ વર્તે. સરળ સંયોજનો માટે તમે ઘટકોને દૂર કરી શકો છો જેની તમને જરૂર નથી:

template
<RouterView v-slot="{ Component }">
  <template v-if="Component">
    <Transition mode="out-in">
      <KeepAlive>
        <Suspense>
          <!-- મુખ્ય સામગ્રી (main content) -->
          <component :is="Component"></component>

          <!-- લોડિંગ સ્ટેટ -->
          <template #fallback>
            લોડ થઈ રહ્યું છે...
          </template>
        </Suspense>
      </KeepAlive>
    </Transition>
  </template>
</RouterView>

Vue Router પાસે ડાયનેમિક ઇમ્પોર્ટ્સનો ઉપયોગ કરીને લેઝીલી લોડિંગ કમ્પોનન્ટ્સ માટે બિલ્ટ-ઇન સપોર્ટ છે. આ એસિંક કમ્પોનન્ટ્સ થી અલગ છે અને હાલમાં તેઓ <Suspense> ને ટ્રિગર કરશે નહીં. જો કે, તેઓ હજુ પણ વંશજો તરીકે એસિંક કમ્પોનન્ટ્સ ધરાવી શકે છે અને તે સામાન્ય રીતે <Suspense> ને ટ્રિગર કરી શકે છે.

નેસ્ટેડ સસ્પેન્સ (Nested Suspense)

  • માત્ર ૩.૩+ માં સપોર્ટેડ છે

જ્યારે આપણી પાસે આ રીતે બહુવિધ એસિંક ઘટકો હોય (નેસ્ટેડ અથવા લેઆઉટ-આધારિત રૂટ્સ માટે સામાન્ય):

template
<Suspense>
  <component :is="DynamicAsyncOuter">
    <component :is="DynamicAsyncInner" />
  </component>
</Suspense>

<Suspense> અપેક્ષા મુજબ ટ્રીની નીચે રહેલા તમામ એસિંક કમ્પોનન્ટ્સને રિઝોલ્વ કરશે તેવી બાઉન્ડ્રી બનાવે છે. જો કે, જ્યારે આપણે DynamicAsyncOuter બદલીએ છીએ, ત્યારે <Suspense> તેની યોગ્ય રીતે રાહ જુએ છે, પરંતુ જ્યારે આપણે DynamicAsyncInner બદલીએ છીએ, ત્યારે નેસ્ટેડ DynamicAsyncInner જ્યાં સુધી તે રિઝોલ્વ ન થાય ત્યાં સુધી ખાલી નોડ રેન્ડર કરે છે (તેના બદલે અગાઉના એક અથવા ફોલબેક સ્લોટને બદલે).

તેને ઉકેલવા માટે, આપણે નેસ્ટેડ ઘટક માટે પેચ (patch) ને હેન્ડલ કરવા માટે નેસ્ટેડ સસ્પેન્સ ધરાવી શકીએ છીએ, જેમ કે:

template
<Suspense>
  <component :is="DynamicAsyncOuter">
    <Suspense suspensible> <!-- આ -->
      <component :is="DynamicAsyncInner" />
    </Suspense>
  </component>
</Suspense>

જો તમે suspensible પ્રોપ સેટ ન કરો, તો આંતરિક <Suspense> પેરેન્ટ <Suspense> દ્વારા સિંક ઘટકની જેમ ગણવામાં આવશે. તેનો અર્થ એ છે કે તેની પાસે પોતાનો ફોલબેક સ્લોટ છે અને જો બંને Dynamic ઘટકો એક જ સમયે બદલાય છે, તો જ્યારે બાળક <Suspense> તેની પોતાની ડિપેન્ડન્સી ટ્રી લોડ કરી રહ્યો હોય ત્યારે ખાલી નોડ્સ અને બહુવિધ પેચિંગ સાયકલ હોઈ શકે છે, જે કદાચ ઇચ્છનીય નથી. જ્યારે સેટ કરવામાં આવે, ત્યારે તમામ એસિંક ડિપેન્ડન્સી હેન્ડલિંગ પેરેન્ટ <Suspense> ને આપવામાં આવે છે (જેમાં ઉત્સર્જિત ઇવેન્ટ્સનો પણ સમાવેશ થાય છે) અને આંતરિક <Suspense> માત્ર ડિપેન્ડન્સી રિઝોલ્યુશન અને પેચિંગ માટે બીજી બાઉન્ડ્રી તરીકે કામ કરે છે.


સંબંધિત

સસ્પેન્સ (Suspense) has loaded