Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何只调用一次带有React useEffect的加载函数_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript 如何只调用一次带有React useEffect的加载函数

Javascript 如何只调用一次带有React useEffect的加载函数,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,React钩子将在每次更改时运行传入函数。可以对其进行优化,使其仅在所需属性更改时调用 如果我想从componentDidMount调用一个初始化函数,并且在发生更改时不再调用它,该怎么办?假设我想加载一个实体,但加载函数不需要来自组件的任何数据。我们如何使用useffecthook实现这一点 class MyComponent extends React.PureComponent { componentDidMount() { loadDataOnlyOnce();

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

如果我想从
componentDidMount
调用一个初始化函数,并且在发生更改时不再调用它,该怎么办?假设我想加载一个实体,但加载函数不需要来自组件的任何数据。我们如何使用
useffect
hook实现这一点

class MyComponent extends React.PureComponent {
    componentDidMount() {
        loadDataOnlyOnce();
    }
    render() { ... }
}
使用钩子时,可以如下所示:

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

如果只想在初始渲染后运行指定给
useffect
的函数,可以将空数组作为第二个参数

函数MyComponent(){
useffect(()=>{
loadDataOnlyOnce();
}, []);
返回{/*…*/};
}

将空数组作为第二个参数传递给
useffect
。这有效地告诉React,引用以下内容:

这告诉React,您的效果不依赖于道具或状态的任何值,因此它永远不需要重新运行

下面是一个代码段,您可以运行它来显示它的工作原理:

函数应用程序(){
const[user,setUser]=React.useState(null);
React.useffect(()=>{
取('https://randomuser.me/api/')
.then(results=>results.json())
。然后(数据=>{
setUser(data.results[0]);
});
},[]);//将空数组传递到装载时仅运行一次。
返回
{user?user.name.first:'正在加载…'}
;
}
ReactDOM.render(,document.getElementById('app'))

TL;DR

useffect(yourCallback,[])
-将仅在第一次渲染后触发回调

详细说明

默认情况下,
useffect
在每次渲染组件后运行(从而产生效果)

在组件中放置
useffect
时,您会告诉React您希望作为效果运行回调。React将在渲染和执行DOM更新后运行效果

如果只传递回调-回调将在每次渲染后运行

如果传递第二个参数(数组),React将在第一次渲染后以及每次更改数组中的一个元素时运行回调。例如,当放置
useffect(()=>console.log('hello'),[someVar,someOtherVar])
时,回调将在第一次渲染后运行,并且在任何一次渲染后,
someVar
someOtherVar
中的一次被更改后运行

通过向第二个参数传递一个空数组,React将在每次渲染数组后进行比较,并将看到没有任何更改,因此仅在第一次渲染后调用回调。

useMountEffect hook 组件挂载后只运行一次函数是一种常见的模式,它证明了它自己的钩子隐藏了实现细节

constusemounteffect=(乐趣)=>useffect(乐趣,[]
在任何功能组件中使用它

function MyComponent() {
    useMountEffect(function) // function will run only once after it has mounted. 
    return <div>...</div>;
}
函数MyComponent(){
useMountEffect(函数)//函数在装入后只运行一次。
返回。。。;
}

关于useMountEffect挂钩


当将
useffect
与第二个数组参数一起使用时,React将在装载(初始渲染)后以及数组中的值更改后运行回调。因为我们传递了一个空数组,所以它只能在装载后运行

我喜欢定义一个
mount
函数,它会像
useMount
一样欺骗EsLint,我发现它更容易解释

const mount = () => {
  console.log('mounted')
  // ...

  const unmount = () => {
    console.log('unmounted')
    // ...
  }
  return unmount
}
useEffect(mount, [])


将依赖项数组留空。希望这能帮助你更好地理解

   useEffect(() => {
      doSomething()
    }, []) 
空依赖项数组在装载时仅运行一次

useEffect(() => {
  doSomething(value)
}, [value])  
值作为依赖项传递。如果自上次以来依赖项已更改,则该效果将再次运行

useEffect(() => {
  doSomething(value)
})  
没有依赖关系。每次渲染后都会调用该函数

function useOnceCall(cb, condition = true) {
  const isCalledRef = React.useRef(false);

  React.useEffect(() => {
    if (condition && !isCalledRef.current) {
      isCalledRef.current = true;
      cb();
    }
  }, [cb, condition]);
}
并使用它

useOnceCall(() => {
  console.log('called');
})


或者,如果存在用于获取数据的参数(例如用户id),则可以在该数组中传递用户id,如果该用户id发生更改,则组件将重新提取数据。很多用例都是这样工作的。是的。。。关于跳绳的更多信息记录在这里:这似乎是最简单的答案,但ESLint抱怨。。。请参阅此线程的其他答案,将loadDataOnlyOnce传递到dependencies数组中即可。这行得通吗?不行,因为当loadDataOnlyOnce更改时(本例中没有,但lint不会抱怨非局部变量),它会重新运行效果。解决方案可能是为钩子创建一个单独的函数,就像这里的另一个答案一样(有效地愚弄了ESLint),或者在第一次运行后设置一个带有布尔值的
useRef
,如果设置了,就不再运行。我非常喜欢您的答案,因为ESLint规则“react hooks/deps”对于空的依赖项列表,将始终失败。例如,著名的CreateReact应用程序模板将强制执行该规则。完全同意@Dynalon。这应该是可接受的解决方案,因为它不干扰ESLint规则。现在,当效果函数需要道具提供的内容时,您可以使用
useMount
,但即使该值在没有linter warnig的情况下更改,也不需要再次运行:
useffect(()=>console.log(props.val),[])
将有缺少依赖项警告,但
使用装载(()=>console.log(props.val))
不会引起警告,但“确实有效”。我不确定并发模式是否会有问题。我不太明白
“react hooks/deps”
仍然抱怨
const useMountEffect=(fun)=>useffect(fun,[])中的空数组。
谢谢!尽管我认为这指向了
“react hooks/deps”
中的一个缺陷,特别是因为这是在挂载上运行东西的标准方式。这个“解决方案”在功能上把问题从组件转移到其他地方,而不是用空的dep从根本上解决问题。谢谢!救了我一天。
useOnceCall(()=>{
  console.log('Fetched Data');
}, isFetched);