Настройка сложного компонента с помощью useEffect и useState?

У меня есть компонент, который я обновляю от запуска простой функции при каждом рендеринге до компонента, который запускается только при обновлении некоторых компонентов:

// dummy functions to simulate calling a service asynchronously 
const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));

const sleep = async fn => {
      await timeout(3000);
      return fn();
};
// imitation of the function
const {useState, useEffect, useCallback} = React;
const CHECKOUT_COUNT_STATE = {NONE:'none', COUNTING:'counting', SUBMITTED:'submitted'};
const Example = () => {
  const [count, setCount] = useState(-1); //uses a redux selector in the real code
  const [countState, setCountState] = useState(CHECKOUT_COUNT_STATE.NONE); //uses a redux selector in the real code
  const [checkoutComponent, setCheckoutComponent] = useState(
    <span> Estimated Stock Count:
        <strong data-co="stock count">Not calculated</strong>
    </span>
  );
  useEffect(()=> {
    if(countState === CHECKOUT_COUNT_STATE.SUBMITTED){
      setCheckoutComponent(<strong>Stock request being submitted&hellip;</strong>)
    } else {
      setCheckoutComponent(
        <span>Estimated Stock Count: {
          countState === CHECKOUT_COUNT_STATE.COUNTING?
            <strong>Calculating&hellip;</strong> :
            <strong data-co="stock count">{count !== -1? count : 'Not Calculated'}</strong>
        }
        </span>
      );
    }
  }, [count, countState])
  // dummy code to simulate async call
  const checkStock = useCallback(async () => {
    await sleep(()=>{
      setCount(Math.floor(Math.random() * (101)));
      setCountState(CHECKOUT_COUNT_STATE.NONE);
    });
  });
  return (
    <div>
      <p>Stock Counter</p>
      <div>{checkoutComponent}</div>
      <button onClick={()=>{
        setTimeout(setCountState(CHECKOUT_COUNT_STATE.COUNTING), 0); checkStock()}
      }>
        Check Stock
      </button>
    <button onClick={() => setCountState(CHECKOUT_COUNT_STATE.SUBMITTED)}>Submit Request</button>
    </div>
  );
};

// Render it
ReactDOM.render(
  <Example title="Example using Hooks:" />,
  document.getElementById("react")
);
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.25/browser-polyfill.min.js"></script>

</head>
<body>
<div id="react"></div>
</body>

Я видел вопросы stackoverflow, которые рекомендуют против этого, но, не усложняя jsx-часть компонента, с условным рендерингом различных частей, я не могу придумать лучшего способа добиться того же поведения.

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *