如何在React中使用带有钩子的生命周期方法



我已经了解了react v16.7.0中引入的钩子。

https://reactjs.org/docs/hooks-intro.html

所以我对钩子的理解是,我们可以在函数组件中处理状态,而无需在react中编写类组件。这真是一个惊人的功能。

但我对在功能组件中使用钩子的情况还不清楚。

import { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

如果我使用钩子,我如何在上面的功能组件中使用生命周期方法?

以下是最常见的生命周期示例:

componentDidMount

将空数组作为第二个参数传递给useEffect(),以便仅在装载时运行回调。

function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, []); // Pass an empty array to run only callback on mount only.
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

componentDidUpdate(松散(

通过只将单个参数传递到useEffect中,它将在每次渲染后运行。这是一个松散的等价物,因为这里有一个细微的区别,即componentDidUpdate不会在第一次渲染后运行,但该挂钩版本在每次渲染后运行。

function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}); // No second argument, so run after every render.
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

componentDidUpdate(严格(

这个例子与上面的例子的不同之处在于,这里的回调不会在初始呈现时运行,严格模仿componentDidUpdate的语义。这是托勒的回答,一切都归功于他。

function Example() {
const [count, setCount] = useState(0);
const firstUpdate = useRef(true);
useLayoutEffect(() => {
if (firstUpdate.current) {
firstUpdate.current = false;
return;
}
console.log('componentDidUpdate');
});
return (
<div>
<p>componentDidUpdate: {count} times</p>
<button
onClick={() => {
setCount(count + 1);
}}
>
Click Me
</button>
</div>
);
}

componentWillUnmount

useEffect的回调参数中返回一个回调,它将在卸载之前被调用。

function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
// Return a callback in useEffect and it will be called before unmounting.
return () => {
console.log('componentWillUnmount!');
};
}, []);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

shouldComponentUpdate

您已经可以使用React.PureComponentReact.memo在组件级别上实现这一点。为了防止重新绘制子组件,这个例子取自React文档:

function Parent({ a, b }) {
// Only re-rendered if `a` changes:
const child1 = useMemo(() => <Child1 a={a} />, [a]);
// Only re-rendered if `b` changes:
const child2 = useMemo(() => <Child2 b={b} />, [b]);
return (
<>
{child1}
{child2}
</>
)
}

getDerivedStateFromProps

同样,取自React文档

function ScrollView({row}) {
let [isScrollingDown, setIsScrollingDown] = useState(false);
let [prevRow, setPrevRow] = useState(null);
if (row !== prevRow) {
// Row changed since last render. Update isScrollingDown.
setIsScrollingDown(prevRow !== null && row > prevRow);
setPrevRow(row);
}
return `Scrolling down: ${isScrollingDown}`;
}

getSnapshotBeforeUpdate

钩子还没有等价物。

componentDidCatch

钩子还没有等价物。

好吧,您并没有真正的生命周期方法。=(但是你可以使用效果挂钩,如图所示https://reactjs.org/docs/hooks-effect.html

效果挂钩将能够复制componentDidMount、componentDidUpdate和componentWillUnmount 的行为

因此,您确实不需要组件中的生命周期方法。效果挂钩取而代之

阅读上面的链接,你会得到一些关于它们如何工作的例子。

React团队为此提供了一个useEffect钩子。让我们以您的示例中的组件为例,添加服务器上传计数,否则我们会将其放入例如componentDidUpdate:中
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
fetch(
'server/url',
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({count}),
}
); 
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

在这个例子中,这似乎不是一个巨大的胜利,因为事实并非如此。但生命周期方法的问题是,在组件中只能得到其中的一个方法。如果你想上传到服务器,触发一个事件,并将消息放入队列,而这些事情都不相关,该怎么办?太糟糕了,他们都挤在componentDidUpdate里。或者,你有n层封装的HOCs来做你想做的n事情。但使用钩子,你可以将所有这些分解为对useEffect的解耦调用,而不需要不必要的HOCs层。

功能组件是纯粹的无状态组件。但在React 16.8中,他们添加了Hooks。钩子可以用来代替状态和生命周期方法。

是的,您可以将useEffect挂钩视为类似

  • 组件DidMount

  • 组件DidUpdate

  • 组件WillUnmount

  • 应该组合组件更新

  • 注意它是componentDidMountcomponentDidUpdate组件WillUnmount&应该组件更新

相关内容

  • 没有找到相关文章

最新更新