以下 React 應用程式顯示水果串列。每個Fruit都有一個“添加到收藏夾”按鈕,該按鈕使用addFav回呼將所述水果添加到父項中的收藏夾串列中。傳入handleAddFav回呼會導致不必要的重新渲染,所以我將它包裝在 auseCallback和Fruitin 中memo。
然而,在其依賴陣列中的useCallback要求會導致每次呼叫時都重新計算。這違背了使用 useCallback 停止重新渲染的目的,因為現在每次添加收藏夾時都會重新渲染。我該如何解決這個問題?favshandleAddFavFruit
import { useState, memo, useCallback } from "react";
import "./styles.css";
const Fruit = memo(({title, id, addFav}) => {
console.log(title, 'rendered')
return (
<div>
<div>{title}</div>
<button onClick={() => addFav(title, id)}>add fav</button>
</div>
)
})
export default function App() {
const [favs, setFavs] = useState([])
const data = [{title: 'apple', id: '1'}, {title:'orange', id:'2'}
, {title:'banana', id:'3'}]
const handleAddFav = useCallback((title, id) => {
setFavs([...favs, {title, id}])
}, [favs])
return (
<div className="App">
<h1>Testing useCallback that sets an array</h1>
<h2>Favorites</h2>
<button onClick={() => setFavs([])}>clear</button>
{
favs.map(({title, id}, i) => <span key={id i}>{title}</span>)
}
{
data.map(({title, id }) => (
<Fruit key={id} title={title} id={id} addFav={handleAddFav}/>
))
}
</div>
);
}
uj5u.com熱心網友回復:
一種方法是使用函式版本setFavs代替,因此它不依賴于外部變數。
const handleAddFav = useCallback((title, id) => {
setFavs(favs => [...favs, {title, id}])
}, [])
對于更一般的情況 - 即使您確實有一個必須重新計算的值,使用useCallback仍然可以減少組件中其他值更改而不是計算值更改的情況的重新渲染。例如
const TheComponent = () => {
const [toggled, setToggled] = useState(false);
const [num, setNum] = useState(5);
const cb = useCallback(() => {
// imagine that this does something that depends on num
}, [num]);
如果cb被傳遞下來,即使它依賴于num,仍然會阻止子級在僅被更改并保持不變useCallback的情況下重新渲染。togglednum
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/433493.html
標籤:javascript 反应 反应钩子 使用回调
上一篇:回圈遍歷字串陣列并將其呈現為React組件中的Prop
下一篇:我如何在反應中替換字串
