在React的官方文档中提到了-
如果你熟悉React类的生命周期方法,你可以思考 将useEffect钩子作为componentDidMount, componentDidUpdate和 componentWillUnmount总和。
我的问题是-我们如何在钩子中使用componentWillMount()生命周期方法?
在React的官方文档中提到了-
如果你熟悉React类的生命周期方法,你可以思考 将useEffect钩子作为componentDidMount, componentDidUpdate和 componentWillUnmount总和。
我的问题是-我们如何在钩子中使用componentWillMount()生命周期方法?
当前回答
简单地在React.useEffect()中放置一个依赖数组作为第二个参数。如果任何依赖项更新,钩子将导致运行并最终更新组件的副作用。
其他回答
这可能不是componentWillMount方法的确切替代方法,但这里有一个方法可以用来实现同样的目标,但要使用useEffect:
首先初始化检索数据的对象为空值,并定义useEffect方法:
const [details, setDetails] = useState("")
useEffect(() => {
retrieveData();
}, []);
const retrieveData = () => {
getData() // get data from the server
.then(response => {
console.log(response.data);
setDetails(response.data)
})
.catch(e => {
console.log(e);
})
}
在JSX中,我们返回一个三元操作符
*return(
<div>
{
details ? (
<div class="">
<p>add Your Jsx Here</p>
</div>
): (
<div>
<h4>Content is still Loading.....</h4>
</div>
)
}
</div>
)*
这将确保在对象'details'中有数据之前,terenary操作符的第二部分会被加载,该操作符会触发useEffect方法,该方法导致在'details'对象中设置从服务器接收到的数据,从而呈现主JSX
只需要简单地在useEffect中添加一个空的依赖数组,它将作为componentDidMount工作。
useEffect(() => {
// Your code here
console.log("componentDidMount")
}, []);
我写了一个自定义钩子,它将在第一次渲染之前运行一个函数。
useBeforeFirstRender.js
import { useState, useEffect } from 'react'
export default (fun) => {
const [hasRendered, setHasRendered] = useState(false)
useEffect(() => setHasRendered(true), [hasRendered])
if (!hasRendered) {
fun()
}
}
用法:
import React, { useEffect } from 'react'
import useBeforeFirstRender from '../hooks/useBeforeFirstRender'
export default () => {
useBeforeFirstRender(() => {
console.log('Do stuff here')
})
return (
<div>
My component
</div>
)
}
这是我如何使用useRef钩子模拟函数组件中的构造函数的方式:
function Component(props) {
const willMount = useRef(true);
if (willMount.current) {
console.log('This runs only once before rendering the component.');
willMount.current = false;
}
return (<h1>Meow world!</h1>);
}
下面是生命周期的例子:
function RenderLog(props) {
console.log('Render log: ' + props.children);
return (<>{props.children}</>);
}
function Component(props) {
console.log('Body');
const [count, setCount] = useState(0);
const willMount = useRef(true);
if (willMount.current) {
console.log('First time load (it runs only once)');
setCount(2);
willMount.current = false;
} else {
console.log('Repeated load');
}
useEffect(() => {
console.log('Component did mount (it runs only once)');
return () => console.log('Component will unmount');
}, []);
useEffect(() => {
console.log('Component did update');
});
useEffect(() => {
console.log('Component will receive props');
}, [count]);
return (
<>
<h1>{count}</h1>
<RenderLog>{count}</RenderLog>
</>
);
}
[Log] Body
[Log] First time load (it runs only once)
[Log] Body
[Log] Repeated load
[Log] Render log: 2
[Log] Component did mount (it runs only once)
[Log] Component did update
[Log] Component will receive props
当然,Class组件没有Body步骤,由于函数和类的概念不同,不可能进行1:1的模拟。
useComponentWillMount钩
const useComponentWillMount = (cb) => {
const willMount = useRef(true)
if (willMount.current) cb()
willMount.current = false
}
当出现顺序问题(比如在另一个脚本之前运行)时,这个钩子可以作为一个保护程序。如果不是这样,请使用useComnponentDidMount,它更符合React钩子的范例。
useComponentDidMount钩
const useComponentDidMount = cb => useEffect(cb, []);
如果你知道你的效果应该只运行一次在开始使用这个解决方案。它只会在组件挂载后运行一次。
useEffect范式
类组件具有生命周期方法,这些方法定义为组件时间轴上的点。钩子不遵循这种范式。相反,效果应该由内容构成。
function Post({postID}){
const [post, setPost] = useState({})
useEffect(()=>{
fetchPosts(postID).then(
(postObject) => setPost(postObject)
)
}, [postID])
...
}
在上面的例子中,效果处理的是获取文章的内容。而不是一个特定的时间点,它有一个它所依赖的值- postID。每次postID得到一个新值(包括初始化),它都会重新运行。
组件将挂载讨论
在类组件中,componentWillMount被认为是遗留的(源1,源2)。它是遗留的,因为它可能运行不止一次,而且还有另一种选择——使用构造函数。这些考虑因素与功能组件无关。