如何从react中的任何位置打开模态



打开时我有一个模态,显示身份验证用户数据,目前,我只能在仪表板上打开模态,但我希望能够从应用程序中的任何位置渲染它。我该如何做到这一点?

仪表板

const [visible, setVisible] = useState(false)
const trigerModal = ()=>(
<ModalCustom visible={visible} setVisible={setVisible}>
<form>
<>
<h3>Select an Account</h3>
<ul className="account">
{accounts && accounts.map((item, i) => (
<li key={item.id}>
<h3>{item.name}</h3>
<h3>{item.email}</h3>         
<h3> {item.phone}</h3>
</li>            
))}
</ul> 
<br />    
</>  

</form>
</ModalCustom>

)

return(
<div>
{trigerModal()}
<button onClick={()=> setVisible(true)}>Open modal</button
</div>
)

配置文件

如何从这个组件触发模态

两个语句几乎可以回答每个反应问题:

  1. 不要更改状态(此处不适用(
  2. 提升状态(这是您问题的答案(

创建一个上下文-将您的应用程序包装在其中,并让任何组件useContext打开一个包含您想要的任何组件的模态:


export const ModalContext = React.createContext();
const ModalProvider = ({children}) => {
const [modalContent,setModalContent] = useState();
return (
<ModalContext.Provider value={
useMemo(() => ({
hide:() => setModalContent(),
open:setModalContent
}),[]
}>
{modalContent ? <Modal>{modalContent}</Modal> : null}
{children}
</ModalContext.Provider>
)  
}

将您的应用程序封装在ModalProvider组件中,以便上下文对您的所有组件都可用:

const AdminDashboard = () => (
<ModalProvider>
<OtherComponents/>
</ModalProvider>
)

SomeLink,位于AdminDashboard内部任何位置的组件都可以使用React.useContext访问ModalProvider中的状态

const SomeLink = () => {
const { open } = React.useContext(ModalContext);
return (
<button onClick={() => open(<SomeModalContent/>)}>Click to Open!</button>
)
}

如果你想从任何地方访问它,你需要使用全局状态(如Redux或Mobx(

如果你想从父组件控制它,你可以使用useRef

不是最多的"反应"-喜欢解决方案,但我不喜欢解决所有问题;反应"-下面是我为我的特定用例解决它的方法。

  1. 创建一个具有静态访问权限的类
  2. 将模态放在dom树的高处/外侧
  3. 在模态组件中设置必要的访问权限

HelperClass

export class ModalHelper {
private static openFunction: (state: boolean) => void;
public static setOpenFunction(f: (state: boolean) => void) {
ModalHelper.openFunction = f;
}
public static setOpen(state: boolean) {
if (ModalHelper.openFunction) {
ModalHelper.openFunction(state);
} else {
console.error("ModalHelper called before setOpenFunction")
}
}
}

样本模态分量

export function ExplainerModal() {
const [open, setOpen] = useState(false);
useEffect(() => {
ModalHelper.setOpenFunction(setOpen);
return () => {
ModalHelper.setOpenFunction(undefined);
};
}, []);
return <>I'm a modal</>
}

从任何地方呼叫

ModalHelper.setOpen(true);

现在请记住,这只适用于一个模态,但当然可以进一步适用于处理多个模态(例如,通过为函数添加dict等(

最新更新