如何在类组件中使用 React Hook
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
好吧,我撒谎了,也不完全是。你不能直接在类组件中使用 Hook,但你可以在包装好的函数组件中使用带有render prop 的Hook来实现这个功能。
在继续之前,如果可以的话,请尽量将类组件转换为函数组件。但如果出于某种原因组件必须保持类组件的形式,那么这种模式也非常适用。在开发成熟的 React 代码库时,您很可能会遇到这种情况。
这种模式的妙处在于,你可以使用钩子函数将新组件构建为函数组件。而那些由于某种原因无法升级的类组件,则可以通过一个轻量级的兼容层——包装组件——获得相同的功能。
我们先来创建一个钩子。
import { useEffect, useState } from "react";
export function useDarkMode() {
// Taken from https://usehooks.com/useDarkMode/
// For this to persist, we'd use localStorage or some other kind
// of way to persist between sessions.
// see e.g. https://usehooks.com/useLocalStorage/
const [enabledState, setEnabledState] = useState(false);
const enabled = enabledState;
useEffect(() => {
const className = "dark-mode";
const element = document.body;
if (enabled) {
element.classList.add(className);
} else {
element.classList.remove(className);
}
}, [enabled]);
return [enabled, setEnabledState];
}
现在我们来创建一个带有 render 属性的函数组件。请注意,该属性并非一定要被直接调用render,但通常这样可以更好地传达其用途。
// I wouldn't normally call a component something like this.
// It's just to convey what it is doing for the purpose of the article
const UseDarkModeHookWrapperComponent = ({ render }) => {
const [darkMode, setDarkMode] = useDarkMode(false);
// Uses the render prop called render that will expose the value and
// setter for the custom hook
return render(darkMode, setDarkMode);
};
现在,让我们在类组件中使用包装组件。
export default class App extends Component {
render() {
return (
<UseDarkModeHookWrapperComponent
render={(darkMode, setDarkMode) => {
return (
<div
style={{
display: "grid",
gridTemplateColumns: "200px",
gap: "2rem",
maxWidth: "50%",
placeItems: "center"
}}
>
<ThemeToggler darkMode={darkMode} setDarkMode={setDarkMode} />
hello
</div>
);
}}
/>
);
}
}
瞧!你已经在类组件中使用钩子函数了。以下是完整的应用程序运行示例。
如果你想看一个实际的例子,Forem 的代码库就是最好的例子。这里是useMediaQuery 钩子,这里是包装组件。如果你想看看它的实际效果,可以在ReadingList 组件中调用它。
照片由Jamie Matociños拍摄,来自Unsplash
文章来源:https://dev.to/nickytonline/using-a-hook-in-a-class-component-3eh2