簡體   English   中英

我的 React 列表項組件不會一次呈現一個

[英]My React list item components don't render one at a time

我不再做很多 React 編程,所以我希望這篇文章有一個簡單的答案。

我有一個模擬生成器 function,它以 2 秒的間隔返回 3 個素數。 當它們返回時,我將產生的每個素數插入到列表中。 在返回所有 3 個素數之前,列表不會呈現。 我只附上相關代碼。

function* testPrimes(addPrime) {
  const primes = [3, 5, 7];
  let time = Date.now();
  let i = 0;
  do {
    const nTime = Date.now();

    if (nTime - time > 2000) {
      yield primes[i++];
      time = nTime;
    }
  } while (i < primes.length);
}

在父組件中,我填充包含的列表(實際上只是 div):

  return (
    <div>
      <div>{appState === RUNNING ? "Running..." : "Stopped"}</div>
      <div className="row">
        {(() => {
          if (appState === RUNNING) {
            for (const prime of testPrimes()) {
              console.log("foo");
              primes.push(<Response {...{ prime, key: prime }} />);
            }
          }
        })()}
        {primes}
      </div>
    </div>
  );

我看到每隔一段時間打印出“foo”,但 <Response> 組件是一次性呈現的。

由於 Javascript 是單線程的,因此 UI 渲染將被阻塞,直到生成所有素數。 請使用setTimeout()代替非 UI 阻塞素數生成。 並且您不應該在render() function 中生成素數,而是在componentDidMount()或其他地方生成素數,並通過更新 state 讓組件重新渲染。

您也可以使用 Pub-Sub 模式。 useEffect中分配事件訂閱。

// Check this library: https://www.npmjs.com/package/pubsub-js
import pubSub from 'pubsub-js';

function *generator() {
  // This yields primes. 
  // For eg:
  const primes = [2, 3, 5, 7, ...]
  let i = 0;
  while (true) {
    yield primes[i++];
  }
  // You can use your own logic get next prime. 
}


const generatorInstance = generator();

function publishPrimes(time = 2000) {
  const prime1 = generatorInstance.next().value;  
  const prime2 = generatorInstance.next().value;  
  const prime3 = generatorInstance.next().value;  

  // Publish 3 primes
  pubSub.publish('NEXT_PRIMES', [prime1, prime2, prime3]);

  // Use setTimeout to publish next 3 after 2 seconds 
  // instead of waiting for 2 seconds to complete using a
  // while loop, which is a **blocking** operation.
  setTimeout(() => {
    publishPrimes();
  }, time);
}

// Do the following inside a useEffect of a component
pubSub.subscribe('NEXT_PRIMES', (primes) => {
  setResponses([
    ...responses, 
    ...primes.map(p => <Response prime={p} />),
  ])
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM