我正在尝试按字母顺序将啤酒名称表示为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元素的渲染列表,但这会产生无休止的渲染循环。
答案 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>
);
};