reactjs - React hooks:可激活状态模式
问题描述
我正在尝试创建一个可以根据道具激活/禁用某些功能的组件。所有这些功能都需要一个必须管理的状态。
我试图考虑一种可能的模式,允许我们在连接的功能不活动的情况下不创建状态。我想到了两种可能的方法:
方式#1
function useFunctionality(initState, enable) {
if (!enable) {
return null;
}
const [funct, updateFunct] = useState(init);
return funct;
}
function Component({ enableFunct }) {
const funct = useFunctionality('test', enableFunct);
return (...);
}
方式#2
function useFunctionality(initState, enable) {
const [funct, updateFunct] = useState(init);
return enable ? funct : null;
}
function Component({ enableFunct }) {
const funct = useFunctionality('test', enableFunct);
return (...);
}
在这两种方式中,钩子都会继续工作。问题是:你觉得哪种方式更正确?有更好的方法来做到这一点吗?
解决方案
两种食谱都有问题。
方式 1 可能允许在组件渲染时有条件地调用钩子,这可能会导致错误并且不鼓励:
不要在循环、条件或嵌套函数中调用 Hook。相反,请始终在 React 函数的顶层使用 Hooks。通过遵循此规则,您可以确保每次渲染组件时都以相同的顺序调用 Hook。这就是允许 React 在多个 useState 和 useEffect 调用之间正确保留 Hooks 状态的原因。
正如这个答案中所解释的,只要保证渲染之间的条件不会改变,就可以放弃这条规则。
保证这一点的一种方法是记住一个条件:
function useFunctionality(initState, enable) {
const condition = useMemo(() => enable, []);
if (!condition)
return null;
const [funct, updateFunct] = useState(initState);
return funct;
}
方式 2 更可取,因为它更清洁,useState
通话也不贵。
两种方式都有相同的问题,它们使用的状态永远不会改变。如果这是意图,那就是 ref 的用例。由于它永远不会改变,因此可以将条件设置为初始值:
function useFunctionality(initState, enable) {
return useRef(enable ? initState: null).current;
}
推荐阅读
- android - Wifi Direct - 此设备地址不适用于 android 10
- react-native - 从 expo 资产中获取标题、专辑和艺术家
- c# - 在 C# 中使用 mysql 文档存储(Nosql)中的日期字段进行过滤
- c# - 属性 vs 方法,哪个更适合与数据成员交互?
- windows - 我在 Julia 中收到一条消息“使用 Plots”,但我不知道如何解决它
- r - 始终在箱线图中显示 tic 标记
- amazon-web-services - 如何在 AWS 上运行 Vue JS 应用程序?
- javascript - 模态弹出窗口不会同时运行
- firebase - Firebase Cloud Functions with Unity 使用 HTTP 可调用函数。需要帮助
- lisp - 如何修改此函数以创建动态 plist