useEffect React钩子将在每次更改时运行传入函数。可以对其进行优化,使其仅在所需属性更改时调用。

如果我想从componentDidMount调用初始化函数,而不是在更改时再次调用它,该怎么办?假设我想加载一个实体,但加载函数不需要来自组件的任何数据。我们如何使用useEffect钩子来实现这个?

class MyComponent extends React.PureComponent {
    componentDidMount() {
        loadDataOnlyOnce();
    }
    render() { ... }
}

如果使用钩子,可能是这样的:

function MyComponent() {
    useEffect(() => {
        loadDataOnlyOnce(); // this will fire on every change :(
    }, [...???]);
    return (...);
}

当前回答

如果您只想在初始呈现后运行给useEffect的函数,可以给它一个空数组作为第二个参数。

function MyComponent() {
  useEffect(() => {
    loadDataOnlyOnce();
  }, []);

  return <div> {/* ... */} </div>;
}

其他回答

以下是我对亚辛回答的看法。

import {useEffect, useRef} from 'react';

const useOnceEffect = (effect: () => void) => {
  const initialRef = useRef(true);

  useEffect(() => {
    if (!initialRef.current) {
      return;
    }
    initialRef.current = false;
    effect();
  }, [effect]);
};

export default useOnceEffect;

用法:

useOnceEffect(
  useCallback(() => {
    nonHookFunc(deps1, deps2);
  }, [deps1, deps2])
);

我在网上花了一段时间后发现的。useEffect在组件挂载时触发一次,然后组件卸载并再次挂载,useEffect再次触发。你得多看看React文档,他们为什么这么做。

我使用了自定义钩子。卸载时,你必须改变你的useRef状态。在这种情况下,不要忘记返回语句:当组件卸载时,useEffect在返回后运行清理函数。

import React, { useEffect, useRef } from "react"

const useDidMountEffect = (
  func: () => void,
  deps: React.DependencyList | undefined
) => {
  const didMount = useRef(false)

  useEffect(() => {
    if (didMount.current) {
      func()
    }
    return () => {
      didMount.current = true
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, deps)
}

export default useDidMountEffect

使用它像正常的useEffect:

  useDidMountEffect(() => {
    // your action    
  }, [])

我在使用React 18时遇到了这个问题。我是这样处理的:

import { useEffect, useRef } from "react";

export default function Component() {
    const isRunned = useRef(false);

    useEffect(() => {
        if(isRunned.current) return;
        isRunned.current = true;
            
         /* CODE THAT SHOULD RUN ONCE */

    }, []);

    return <div> content </div>;
}

看看这里他们是如何解释为什么useEffect被多次调用的。

如果你只是在渲染后调用useeffect中的函数,你添加一个空数组作为useeffect的第二个参数

useEffect=(()=>{
   functionName(firstName,lastName);
},[firstName,lastName])

如果您只想在初始呈现后运行给useEffect的函数,可以给它一个空数组作为第二个参数。

function MyComponent() {
  useEffect(() => {
    loadDataOnlyOnce();
  }, []);

  return <div> {/* ... */} </div>;
}