为什么这会使用React钩子创建无限渲染循环?

时间:2019-07-01 23:44:57

标签: reactjs react-hooks

我正在尝试按字母顺序将啤酒名称表示为H1元素,并且我是React Hooks的新手,但这似乎会导致重新渲染循环

“啤酒”组件从“ Home”组件传递了一系列啤酒作为道具,该啤酒利用了“ useEffect Hook”,尽管我不确定,但我怀疑这可能是罪魁祸首。

const Beer = ({ beer }) => {
  const [beers, setBeers] = useState([]);
  let rendered;
  if (beer === undefined) {
    rendered = <Spinner />;
  } else {
    rendered = beer.map(beer => beer.name);
    setBeers(rendered.sort());
    rendered = beers.map(beer => <h1>{beer}</h1>);
  }

  return <div>{rendered}</div>;
};

const Home = () => {
  const [beers, setBeers] = useState();
  useEffect(() => {
    const getBeers = async () => {
      const beerData = await fetch('https://api.punkapi.com/v2/beers');
      const beers = await beerData.json();
      console.log(beers);
      setBeers(beers);
    };
    getBeers();
  }, []);

  return (
    <div>
      <h1>Punk Beers</h1>
      <Beer beer={beers} />
    </div>
  );
};

我希望会有一个H1元素的渲染列表,但这会产生无休止的渲染循环。

1 个答案:

答案 0 :(得分:1)

当您在setBeers内调用Beer时,React将使用提供给beers状态变量的更新值来重新呈现组件(即重新执行函数)。 / p>

您通常不需要将道具复制到这样的状态。如果您的组件在展示前会对道具执行昂贵的操作,则可能需要use memoization to cache the result

在这种情况下,简单地对beers进行排序并不昂贵,除非您的数组长成千上万个项目,因此不需要优化。

const Beer = ({ beers }) => (
  beers ? (
    [...beers].sort().map((beer, index) => 
      <h1 key={index}>{beer}</h1>
    )
  ) : (
    <Spinner />
  )
)

const Home = () => {
  const [beers, setBeers] = useState();
  useEffect(() => {
    const getBeers = async () => {
      const beerData = await fetch('https://api.punkapi.com/v2/beers');
      const beers = await beerData.json();
      console.log(beers);
      setBeers(beers);
    };
    getBeers();
  }, []);

  return (
    <div>
      <h1>Punk Beers</h1>
      <Beer beers={beers} />
    </div>
  );
};