![](/img/trans.png)
[英]React Hooks - Updating state using props without event handlers
[英]Correct way to create event handlers using hooks in React?
在典型的基於類的 React 組件中,這是我創建事件處理程序的方式:
class MyComponent extends Component {
handleClick = () => {
...
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}
但是,當我使用基於鈎子的函數范式時,我發現自己有兩個選擇:
const MyComponent = () => {
const [handleClick] = useState(() => () => {
...
});
return <button onClick={handleClick}>Click Me</button>;
};
或者:
const MyComponent = () => {
const handleClick = useRef(() => {
...
});
return <button onClick={handleClick.current}>Click Me</button>;
};
哪一個客觀上更好,原因是什么? 有沒有我還沒有聽說過或發現的另一種(更好的)方法?
感謝您的幫助。
編輯:我在 CodeSandbox 上放了一個例子,展示了這兩種方法。 從那里的代碼中可以看出,兩者似乎都沒有不必要地在每次渲染時重新創建事件處理程序,因此我認為不可能出現性能問題。
我不推薦useState
或useRef
。
你實際上根本不需要任何鈎子。 在許多情況下,我建議簡單地這樣做:
const MyComponent = () => {
const handleClick = (e) => {
//...
}
return <button onClick={handleClick}>Click Me</button>;
};
但是,有時建議避免在渲染函數中聲明函數(例如jsx-no-lambda
tslint 規則)。 這有兩個原因:
我不會太擔心第一點:鈎子將在函數內部聲明函數,並且該成本不太可能成為您的應用程序性能的主要因素。
但是第二點有時是有效的:如果一個組件被優化(例如使用React.memo
或被定義為一個PureComponent
)以便它只在提供新的 props 時重新渲染,傳遞一個新的函數實例可能會導致組件重新渲染- 不必要地渲染。
為了解決這個問題,React 提供了useCallback
鈎子,用於useCallback
回調:
const MyComponent = () => {
const handleClick = useCallback((e) => {
//...
}, [/* deps */])
return <OptimizedButtonComponent onClick={handleClick}>Click Me</button>;
};
useCallback
只會在必要時返回一個新函數(每當 deps 數組中的值發生變化時),因此OptimizedButtonComponent
不會重新渲染超過必要的次數。 所以這解決了問題#2。 (請注意,它沒有解決問題 #1,每次渲染時,仍會創建一個新函數並將其傳遞給useCallback
)
但我只會在必要時這樣做。 您可以將每個回調包裝在useCallback
,它會起作用……但在大多數情況下,它沒有任何幫助:帶有<button>
原始示例不會從記憶化回調中受益,因為<button>
不是一個優化的組件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.