const TestComponent = props => {
const testFunction = () => {
// does something.
};
useEffect(() => {
testFunction();
// The effect calls testFunction, hence it should declare it as a dependency
// Otherwise, if something about testFunction changes (e.g. the data it uses), the effect would run the outdated version of testFunction
}, [testFunction]);
};
const TestComponent = props => {
const testFunction = useCallback(() => {
// does something.
}, []);
useEffect(() => {
testFunction();
// The effect calls testFunction, hence it should declare it as a dependency
// Otherwise, if something about testFunction changes (e.g. the data it uses), the effect would run the outdated version of testFunction
}, [testFunction]);
};
让我们举一个例子,如果我运行下面的代码并单击第一个按钮,它将始终重新渲染MemoComponent以及。为什么是因为我们每次都在传递新的onClick函数给这个。为了避免重新渲染MemoComponent,我们可以做的是wrap onClick to usefallback。每当你想创建一个新的函数时,将状态传递给依赖数组。 如果你想对状态变化执行一些操作,你可以在useEffect中编写。
useEffect(() => {
// execute when state changed
() => {
// execute before state is changed
}
}, [state]);
OR
useEffect(() => {
// execute when state changed
() => {
// execute before state is changed
}
}, []);
4条答案
按热度按时间bpzcxfmw1#
不,它们不一样。
useEffect-用于在组件发生更改时运行副作用。
useEffect
不会返回任何内容。它只是运行组件中的一段代码。useCallback-虽然
useCallback
返回一个函数,但它实际上并不执行代码。重要的是要理解函数是JavaScript中的对象。如果不使用useCallback
,则在组件内部定义的函数将在组件重新构建时重新创建。示例
考虑这个例子,这个组件将进入无限循环。想想为什么?
因为在每次渲染时,testFunction都将被重新创建,并且我们已经知道,当testFunction发生变化时,
useEffect
将运行代码。由于testFunction在每次渲染时都会改变,useEffect
将继续运行,因此是一个无限循环。为了解决这个问题,我们必须告诉react,嘿,请不要在每次渲染时重新创建testFunction,只在第一次渲染时创建它(或者当它所依赖的东西发生变化时)。
这不会是一个无限循环,因为testFunction的示例只会在第一次渲染时改变,因此
useEffect
只会运行一次。o8x7eapl2#
他们太不一样了。
useEffect
将 * 在依赖数组更改时运行 * 内部的函数。useCallback
将在依赖数组改变时 * 创建一个新函数 *。您不能单独使用
useCallback
切换useEffect
,因为您还需要逻辑来运行新创建的函数。(我想如果你也使用ref的话,你也可以实现这个,但那会很奇怪。你不能用
useEffect
切换useCallback
,因为你通常不想立即运行新创建的函数--相反,你通常想把它作为一个 prop 传递给其他组件。useCallback
的存在主要是为了优化,以减少子组件的重新呈现。7y4bm7vi3#
useEffect会在依赖数组发生变化时运行内部函数。
useCallback会在依赖数组发生变化时创建一个新函数。
让我们举一个例子,如果我运行下面的代码并单击第一个按钮,它将始终重新渲染MemoComponent以及。为什么是因为我们每次都在传递新的onClick函数给这个。为了避免重新渲染MemoComponent,我们可以做的是wrap onClick to usefallback。每当你想创建一个新的函数时,将状态传递给依赖数组。
如果你想对状态变化执行一些操作,你可以在useEffect中编写。
8zzbczxx4#
使用效果
它是类组件生命周期方法componentDidMount、componentWillUnmount、componentDidUpdate等的替代方法。您也可以使用它来在依赖关系更改时创建副作用,即如果某个变量发生变化,请执行此操作。
每当你有一些逻辑被执行作为状态变化的React或在变化即将发生之前。
使用回调
在每次渲染时,功能组件中的所有内容都将再次运行。如果子组件依赖于父组件的函数,则每次父组件重新渲染时,子组件将重新渲染,即使该函数“没有更改”(引用更改,但函数所做的不会更改)。它用于优化,避免不必要的子级渲染,使函数仅在依赖项更改时更改引用。当一个函数是副作用的依赖项时,你应该使用它。使用效果。
每当你有一个依赖于某些状态的函数时。这个钩子用于性能优化,除非依赖状态被改变,否则可以防止组件内的函数被重新分配。
如果没有useCallback,myFunction将在每次渲染时重新分配。因此,它使用了更多的计算时间,就像useCallback一样。