Synthbot

Loop controls - old

Oct 22nd, 2020 (edited)
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { useState } from 'react';
  2.  
  3. /**
  4.  * Follow a UI flow that loops over an array. Expected usage:
  5.  *
  6.  * Declare the control flow functions at the top of the parent React component:
  7.  *   const { currentItem, hasNext, begin, moveToNext, terminate } = useLoopControls();
  8.  * Call begin() to begin the loop:
  9.  *    begin(arrayItemsToLoopOver);
  10.  * Use hasNext and currentItem to display the relevant UI:
  11.  *    <SingleItemHandler visible={hasNext} value={currentItem} ... />
  12.  * Once done with the current item, move to the next item with moveToNext():
  13.  *    <SingleItemHandler ... onComplete={moveToNext} ... />
  14.  * Abort the loop using terminate():
  15.  *    <SingleItemHandler ... onError={terminate} />
  16.  * Handle any final steps and cleanup with the promise returned from begin():
  17.  *    begin(...).then(...).catch(...);
  18.  */
  19. export default () => {
  20.   let [currentArray, setCurrentArray] = useState();
  21.   let [currentIndex, setCurrentIndex] = useState();
  22.   let [currentItem, setCurrentItem] = useState();
  23.   let [hasNext, setHasNext] = useState(false);
  24.  
  25.   let [resolveArray, setResolveArray] = useState();
  26.   let [rejectArray, setRejectArray] = useState();
  27.  
  28.   const begin = (array) => {
  29.     return new Promise((resolve, reject) => {
  30.       if (array.length === 0) {
  31.         resolve();
  32.         return;
  33.       }
  34.  
  35.       // retain callbacks for when the loop is complete
  36.       resolveArray = resolve;
  37.       setResolveArray(() => resolveArray);
  38.       rejectArray = reject;
  39.       setRejectArray(() => rejectArray);
  40.  
  41.       // initialize the loop
  42.       setCurrentArray(currentArray = array);
  43.       setHasNext(hasNext = true);
  44.       setCurrentIndex(currentIndex = 0);
  45.       setCurrentItem(currentItem = currentArray[0]);
  46.     });
  47.   }
  48.  
  49.   /**
  50.    * Complete the loop with an error.
  51.    */
  52.   const terminate = () => {
  53.     setHasNext(hasNext = false);
  54.     rejectArray && rejectArray();
  55.   }
  56.  
  57.   /**
  58.    * Move to the next loop iteration.
  59.    */
  60.   const moveToNext = () => {
  61.     if (!hasNext) {
  62.       throw new Error('attempted to iterate past the end of the loop');
  63.     }
  64.  
  65.     let newIndex = currentIndex + 1;
  66.  
  67.     if (newIndex >= currentArray.length) {
  68.       // terminate the loop successfully
  69.       setHasNext(hasNext = false);
  70.       setCurrentIndex(currentIndex = newIndex);
  71.       setCurrentItem(currentItem = null);
  72.       resolveArray();
  73.       return;
  74.     }
  75.  
  76.     setCurrentIndex(currentIndex = newIndex);
  77.     setCurrentItem(currentItem = currentArray[newIndex]);
  78.   }
  79.  
  80.   return { currentItem, hasNext, begin, moveToNext, terminate };
  81. }
Advertisement
Add Comment
Please, Sign In to add comment