javascript - 如果不指定依赖项,useEffect() 有什么意义

标签 javascript reactjs react-hooks use-effect

我在功能组件中使用 React Hook ,想知道当您不指定依赖项时 useEffect 的用途是什么。我知道它用于副作用的文档状态,但我的问题是为什么这些副作用不能只在功能组件内使用纯 JS 运行?作为一个非常基本的示例,我正在使用以下代码:

import {useEffect, useState} from 'react'

function Child () {

  const [clickCount, updateCount] = useState(0)

  console.log('Run outside of useEffect')

  useEffect(()=>{
    console.log("Run inside of useEffect")
  })


  return (

    <button onClick = {() => updateCount(clickCount+1)}> Child COmponent </button>
  )
}

export default Child

正如您所期望的那样,它基本上只是一个普通的 JS 函数,在每次由单击按钮引起的重新渲染时,两个 console.log 都会被执行。

我理解为什么您可能想要在如下情况下使用 useEffect,您只想在某些特定更改时运行 useEffect:

import {useEffect, useState} from 'react'

function Child () {

  const [clickCount, updateCount] = useState(0)

  console.log('Run outside of useEffect')

  //this now only runs when `someVariable` changes
  useEffect(()=>{
    
    console.log("Run inside of useEffect")
  }, [someVariable])


  return (

    <button onClick = {() => updateCount(clickCount+1)}> Child COmponent </button>
  )
}

export default Child

但这引出了一个问题,除非您将依赖矩阵指定为第二个参数,否则使用 useEffect 有什么意义? side effects 就不能用纯 JS 正常运行吗?

最佳答案

来自docs :

effects scheduled with useEffect don’t block the browser from updating the screen. This makes your app feel more responsive. The majority of effects don’t need to happen synchronously.

useEffect Hook 中的代码在 DOM 更新后运行。这就是区别。

例子:

function App() {

  let [hi, setHi] = React.useState(false);
  let [inEffect, setInEffect] = React.useState(true);
  let msg = inEffect ? "useEffect (DOM will be updated immediately)" : "functional component (it will block DOM update)";
  
  return (
    <React.Fragment>
      <p>
        Long-running code is in {msg} {" "}
        <button onClick={() => (setInEffect(!inEffect), setHi(false))}>switch</button>
      </p>
      <button onClick={() => setHi(true)}>Say Hi</button>
      { hi ? <Hi {...{inEffect}}/> : null }
    </React.Fragment>
  );
}

function Hi({inEffect}) {
  !inEffect && block();
  React.useEffect(() => inEffect && block());
  return <h1>Hi!</h1>
}

function block(time = 2000) {
  const now = Date.now();
  while(now + time > Date.now());
}


ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

关于javascript - 如果不指定依赖项,useEffect() 有什么意义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64523865/

相关文章:

reactjs - 在 DatePicker for AntD 中隐藏日历图标(后缀图标)的正确方法

reactjs - 以编程方式导航 : React Router V4+ Typescript giving error

reactjs - 一次只能展开折叠 (material-ui) - React

javascript - 如何获取最后一个和之前附加的div属性和内容onclick?

javascript - 将参数传递给 meteor 上的不同 jscript

javascript - JS元素插入导致意外移位

Javascript new Date() 接受月末之后的日期

javascript - React 表格​​搜索功能

javascript - 使用 Next.js 和钩子(Hook)设置间隔

javascript - 这是检测 react 组件中第一次渲染的正确方法