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

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

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


当前回答

对于大多数人来说,这可能很清楚,但请记住,在函数组件体内调用的函数充当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

其他回答

有一个很好的解决方案来实现componentDidMount和componentWillUnmount与useEffect。

根据文档,useEffect可以返回一个“清理”函数。该函数不会在第一次useEffect调用时调用,只在后续调用时调用。

因此,如果我们使用useEffect钩子而没有任何依赖关系,那么该钩子只会在组件挂载时被调用,而“cleanup”函数则会在组件卸载时被调用。

useEffect(() => {
    console.log('componentDidMount');

    return () => {
        console.log('componentWillUnmount');
    };
}, []);

只有在卸载组件时才调用清理返回函数调用。

希望这能有所帮助。

正如react文档中所述:

您可能会认为我们需要一个单独的效果来执行 清理。但是添加和删除订阅的代码非常紧凑 useEffect的设计是为了将它们放在一起。如果你的效果 返回一个函数,React会在清理的时候运行它:

useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

所以我们唯一需要在钩子中使用componentWillUnmount的是在useEffect中返回一个函数,如上所述。

componentWillMount已弃用(正如在其他评论中提到的),原因是我认为它很容易被一个简单的HOC处理。

const withComponentWillMount = (WrappedComponent, handler) => {
  return (props) => {
    return handler(props) ? <WrappedComponent {...props} /> : null;
  }
}

我通常在我的项目中实现这个解决方案。使用此HOC,如果处理程序返回false,则组件内部不运行任何内容,包括钩子。

您可以修改useMemo钩子来模仿componentWillMount生命周期事件。 只做:

const Component = () => {
   useMemo(() => {
     // componentWillMount events
   },[]);
   useEffect(() => {
     // componentDidMount events
     return () => {
       // componentWillUnmount events
     }
   }, []);
};

您需要在任何与您的状态交互之前保留useMemo钩子。这不是它的意图,但它适用于我的所有componentWillMount问题。

这是可行的,因为useMemo并不需要实际返回一个值,你也不必实际使用它作为任何东西,但由于它基于依赖关系记住了一个只会运行一次的值(“[]”),并且它位于我们的组件之上,它在组件挂载之前运行一次。

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