重新渲染过多(React,useState)

时间:2020-06-23 10:10:56

标签: javascript reactjs

这个想法是,当用户从键盘上按下正确的字母(鸟名的第一个字母)时,鸟数组中的第一个鸟名将被删除,因此用户可以继续猜测直到该数组被空的。我得到一个错误错误:重新渲染过多。 React限制了渲染次数以防止无限循环。我试图用useEffect来解决问题,但是它没有用(也许我没有正确使用它)。

以下是代码:

import React, { useState, useEffect } from 'react';

// Usage
function App() {

  const [birds, setBirds] = useState(['rambo', 'rio', 'charlie', 'coco', 'cleo', 'sunny', 'daffy', 'aldo', 'daisy', 'baxter'])
  const [currentBird, setCurrentBird] = useState(birds[0])
  const [birdArray, setBirdArray] = useState(currentBird.split(""))
  // Call our hook for each key that we'd like to monitor
  const birdFirstLetter = useKeyPress(birdArray[0]); // return true or false



  return (
    <div>
      <div>
        {birdFirstLetter && setBirds(birds.slice(1))}
      </div>
    </div>
  );
}

// Hook
function useKeyPress(targetKey) {
  // State for keeping track of whether key is pressed
  const [keyPressed, setKeyPressed] = useState(false);

  // If pressed key is our target key then set to true
  function downHandler({ key }) {
    if (key === targetKey) {
      setKeyPressed(true);
    }
  }

  // If released key is our target key then set to false
  const upHandler = ({ key }) => {
    if (key === targetKey) {
      setKeyPressed(false);
    }
  };

  // Add event listeners
  useEffect(() => {
    window.addEventListener('keydown', downHandler);
    window.addEventListener('keyup', upHandler);
    // Remove event listeners on cleanup
    return () => {
      window.removeEventListener('keydown', downHandler);
      window.removeEventListener('keyup', upHandler);
    };
  }, []); // Empty array ensures that effect is only run on mount and unmount

  return keyPressed;
}

export default App;

这种方式也不起作用(结果相同):

function App() {

  const [birds, setBirds] = useState(['rambo', 'rio', 'charlie', 'coco', 'cleo', 'sunny', 'daffy', 'aldo', 'daisy', 'baxter'])
  const [currentBird, setCurrentBird] = useState(birds[0])
  const [birdArray, setBirdArray] = useState(currentBird.split(""))
  // Call our hook for each key that we'd like to monitor
  const birdFirstLetter = useKeyPress(birdArray[0]); // return true or false

  if (birdFirstLetter){
    setBirds(birds.slice(1))
  }



  return (
    <div>
      <div>
        {/*birdFirstLetter && setBirds(birds.slice(1))*/}
      </div>
    </div>
  );
}

...
...
...

export default App

2 个答案:

答案 0 :(得分:0)

反应的原则之一: 永远不要在jsx中更改状态或渲染它会溢出堆栈限制。 在render或jsx中进行状态更改会导致组件重新呈现,这就是为什么您获得太多重新呈现的原因。

从JSX中删除“ setBirds”,它不会引发错误。

答案 1 :(得分:0)

你的意思是这样吗?

const removeElement = () => {
   setBirds(birds.slice(1))
}

<div onKeyPress={removeElement}>
   {/*birdFirstLetter && setBirds(birds.slice(1))*/}
</div>