英文:
What is the right way to use the useCallback hook?
问题
我有一个自定义输入组件,如下所示:
import React, { useState, useCallback } from 'react'
function MyCustomInput ({value: initialValue = '0'}) {
const [value, setValue] = useState(initialValue)
const handleChange = useCallback(
value => {
setValue(value)
},
[setValue]
)
return (
<SomeInputComponent onChange={handleChange}/>
)
}
React中的useCallback
实现在文档中说:
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b]
)
根据文档的实现,正确的方式应该是:
const handleChange = useCallback(
value => {
setValue(value)
},
[value] // 而不是[setValue]
)
但是这样做会使useCallback
的使用变得毫无意义,因为handleChange
每次value
状态更新时都会获得一个新的函数引用,这将导致不必要的重新渲染<SomeInputComponent>
组件。我的实现是否有错误?
1: https://reactjs.org/docs/hooks-reference.html#usecallback
英文:
I have an custom input component, like so:
import React, { useState, useCallback } from 'react'
function MyCustomInput ({value: initialValue = '0'}) {
const [value, setValue] = useState(initialValue)
const handleChange = useCallback(
value => {
setValue(value)
},
[setValue]
)
return (
<SomeInputComponent onChange={handleChange}/>
)
}
The useCallback implementation in React doc says:
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b]
)
Now as per the doc implementation, the correct way should be:
const handleChange = useCallback(
value => {
setValue(value)
},
[value] // And not, [setValue]
)
But this would make the use of useCallback
worthless as handleChange
would start to get a new func reference each time the value
state updates which would lead to unnecessary rerender of my <SomeInputComponent>
component. Is my implementation incorrect?
1: https://reactjs.org/docs/hooks-reference.html#usecallback
答案1
得分: 1
你应该包括创建函数所需的所有内容,value
在调用函数时作为普通参数传递。
在这种情况下,构建函数所需的唯一依赖项是 setValue
:
const handleChange = useCallback(
value => {
setValue(value)
}, [setValue]
)
然而,由于setState
、dispatch
(来自useReducer
)和useRef
被认为是静态的,你可以从依赖项列表中省略它们。exhaustive-deps规则有一个名为isDefinitelyStaticDependency(reference)
的函数,它查找并“批准”这些函数为静态函数。因此,你的代码应该是这样的:
const handleChange = useCallback(
value => {
setValue(value)
}, []
)
英文:
You should include everything that is needed to create the function, the value
is passed as a normal parameter when the function is called.
The only dependency needed to build the function in this case is setValue
:
const handleChange = useCallback(
value => {
setValue(value)
}, [setValue]
)
However, since setState
, dispatch
(from useReducer
), and useRef
are known to be static, you can omit them from the list of dependencies. The exhaustive-deps rule has a function isDefinitelyStaticDependency(reference)
that looks for and "approves" this functions as static. So your code should be:
const handleChange = useCallback(
value => {
setValue(value)
}, []
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论