在React的官方文档中提到了-

如果你熟悉React类的生命周期方法,你可以思考 将useEffect钩子作为componentDidMount, componentDidUpdate和 componentWillUnmount总和。

我的问题是-我们如何在钩子中使用componentWillMount()生命周期方法?


当前回答

React组件是一个函数?所以只要让componentWillMount moment成为return语句之前的函数体。

function componentWillMountMomentIsHere() {
  console.log('component will mount')
}


function AnyComponent(){
  const [greeting, setGreeting] = useState('Hello')

  componentWillMountMomentIsHere()

  
  return <h1>{greeting}</h1>
}

其他回答

简单地在React.useEffect()中放置一个依赖数组作为第二个参数。如果任何依赖项更新,钩子将导致运行并最终更新组件的副作用。

对于大多数人来说,这可能很清楚,但请记住,在函数组件体内调用的函数充当beforeRender。这并没有回答在ComponentWillMount上运行代码的问题(在第一次渲染之前),但由于它是相关的,可能会帮助其他人,所以我把它留在这里。

const MyComponent = () => {
  const [counter, setCounter] = useState(0)
  
  useEffect(() => {
    console.log('after render')
  })

  const iterate = () => {
    setCounter(prevCounter => prevCounter+1)
  }

  const beforeRender = () => {
    console.log('before render')
  }

  beforeRender()

  return (
    <div>
      <div>{counter}</div>
      <button onClick={iterate}>Re-render</button>
    </div>
  )
}

export default MyComponent

本·卡普的答案对我来说似乎是唯一有效的答案。

但由于我们使用的是函数式方法,另一种方法可以受益于闭包和HoC:

const InjectWillmount = function(Node, willMountCallback) {
  let isCalled = true;
  return function() {
    if (isCalled) {
      willMountCallback();
      isCalled = false;
    }
    return Node;
  };
};

然后使用它:

const YourNewComponent = InjectWillmount(<YourComponent />, () => {
  console.log("your pre-mount logic here");
});

React组件是一个函数?所以只要让componentWillMount moment成为return语句之前的函数体。

function componentWillMountMomentIsHere() {
  console.log('component will mount')
}


function AnyComponent(){
  const [greeting, setGreeting] = useState('Hello')

  componentWillMountMomentIsHere()

  
  return <h1>{greeting}</h1>
}

useLayoutEffect可以用一个空的观察者集([])来完成这一点,如果功能实际上类似componentWillMount——它将在第一个内容到达DOM之前运行——尽管实际上有两个更新,但它们在绘制到屏幕之前是同步的。

例如:


function MyComponent({ ...andItsProps }) {
     useLayoutEffect(()=> {
          console.log('I am about to render!');
     },[]);

     return (<div>some content</div>);
}

与useState相比,使用初始化器/setter或useEffect的好处是,尽管它可以计算一个渲染传递,但用户不会注意到DOM的实际重新渲染,并且它是在第一次明显的渲染之前运行的,而useEffect则不是这样。缺点当然是在你的第一次渲染中有轻微的延迟,因为在绘制到屏幕之前必须进行检查/更新。不过,这确实取决于您的用例。

我个人认为,useMemo在一些特定的情况下是很好的,当你需要做一些沉重的事情时——只要你记住这是例外与规范。