我正在尝试为我的组件提供一个 useMessage
Hook 。
在我的应用程序中,Panel
是最大的组件,即母组件,其中有一个 Message
组件,该组件使用 Material UI 的 Snackbar
code> 显示消息和警报。
这是一个code sandbox
组件以这种方式使用我的钩子(Hook):
import useMessage from './useMessage'
const SomeComponent = () => {
const { success, error } = useMessage()
return <button onClick={success('some message')}>Show success</button>
}
但是,它不会改变严重性
,而且很多时候消息都是空的。它没有按照我期望的方式工作。
如何修复它?
最佳答案
问题
看来 useMessage
Hook 中的 useEffect
Hook 是所有问题的根源,特别是它与 hide
函数的交互。
const hide = () => {
setIsMessageShown(false);
};
...
useEffect(() => {
if (message && severity) {
setIsMessageShown(true);
}
return () => {
if (isMessageShown === false) {
setMessage(null);
setSeverity(null);
}
};
}, [
message,
setMessage,
severity,
setSeverity,
isMessageShown,
setIsMessageShown
]);
当调用 hide
时,它会排队状态更新以将 isMessageShown
状态切换为 false。 isMessageShown
是 useEffect
的依赖项,并且有一个条件检查是否存在真实的消息
和严重性
状态。因为这也没有被清除,所以另一个状态更新被排队以将 isMessageShown
状态切换回 true。同时,useEffect
Hook 返回一个清理函数,然后将状态更新排入队列以清除 message
和 severity
状态,但是 >Snackbar
和 Alert
组件仍然显示。
从现在开始似乎存在状态同步问题,这就是为什么警报在第一次调用后不起作用的原因。
解决方案
注释掉或删除 useEffect
Hook 似乎可以完全解决您在codesandbox中描述和重现的问题。
这是更新的 useMessage
Hook 。
import { usePanel } from "./PanelContext";
const useMessage = () => {
const { setIsMessageShown, setMessage, setSeverity } = usePanel();
const show = (data, action, type) => {
if (data && data.message) {
data = data.message;
}
setMessage(data);
setSeverity(type);
setIsMessageShown(true);
};
const success = (data, action) => {
show(data, action, "success");
};
const info = (data, action) => {
show(data, action, "info");
};
const warning = (data, action) => {
show(data, action, "warning");
};
const error = (data, action) => {
show(data, action, "error");
};
const hide = () => {
setIsMessageShown(false);
};
return {
success,
info,
warning,
error,
show,
hide
};
};
export default useMessage;
我做了一些重构来集中面板上下文代码和逻辑
PanelContext.js
import React, { useContext, useState } from "react";
export const PanelContext = React.createContext();
export const usePanel = () => useContext(PanelContext);
const PanelProvider = ({ children }) => {
const [isMessageShown, setIsMessageShown] = useState();
const [message, setMessage] = useState();
const [severity, setSeverity] = useState();
return (
<PanelContext.Provider
value={{
isMessageShown,
setIsMessageShown,
message,
setMessage,
severity,
setSeverity
}}
>
{children}
</PanelContext.Provider>
);
}
export default PanelProvider;
关于reactjs - 无法使该消息 Hook 在 React 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72640471/