javascript - 创建调用不同功能的全局模态
问题描述
例如,我有一个带有对话框的模式来确认保存更改。此模式用于多个组件,但它必须根据组件调用不同的函数。它调用的函数存在于组件内部。
最好创建一个可重用的全局模态组件(使用 Redux 或 React Context),它可以根据使用的屏幕接受不同的功能
我知道你不能在减速器中存储不可序列化的值,所以我想知道是否有一种优雅的方法来处理这种情况而不必在每个单独的组件中导入模态?
解决方案
您可以定义 aModalProvider
并将其放在您的ReduxProvider
or之后ContextProvider
以使用状态(存储)值和操作。让我们用一些示例代码来演示它,我指的是使用Redux
,但您可以使用ContextApi
相同的。
首先,定义一个通用/全局模态提供者
import React from 'react';
import {useSelector} from 'react-redux';
const ModalProvider = ({children}) => {
const modal = useSelector(state => state.modal)
return(
<ModalComponent isVisible={modal.isVisible} title={modal.title} >
{children}
</ModalComponent>
)
}
export default ModalProvider;
注意: ModalComponent
是一个示例模态组件,它提供标题、模态状态和您在应用程序中可能需要的其他选项。
现在,是时候ModalProvider
在根组件中使用了:
import ReduxProvider from 'path/to/your/redux/provider';
import ModalProvider from 'path/to/your/modal/proivder';
const App = () => (
<ReduxProvider store={store} >
// put the ModalProvider after the ReduxProvider
<ModalProvider>
// your other providers, toasts, routes ...
</ModalProvider>
</ReduxProvider>
)
export default App;
注意: ModalProvider
必须放在ReduxProvider
消费状态对象之后。
通过定义正确的reducer
and来完成 redux 的实现actions
:
示例操作:
const OPEN_MODAL = "OPEN_MODAL";
const CLOSE_MODAL = "CLOSE_MODAL";
const openModal = (modalData) => ({type: OEPN_MODAL, payload: modalData})
const closeModal = () => ({type: CLOSE_MODAL})
并且,减速器:
const initialState = {
isVisible: false,
title: "",
description: "",
// and so on for the rest of details depend on your application
}
const modalReducer = (state=initialState, action) => {
switch(action.type) {
case OPEN_MODAL:
return {
...state,
isVisible: true,
title: action.payload.title,
description: action.payload.description
}
case CLOSE_MODAL: {
return {
...state,
isVisible: false,
title: "",
description: ""
}
default:
return state;
}
}
}
重要的提示:
您可能需要一个toggleModal
动作或其他动作来控制您的模态行为,因此请按照您的意愿实施它们。
最后,使用dispatch
方法在组件/页面中调度正确的操作。
import React from 'react';
import {useDispatch} from 'react-redux';
const SampleComponet = () => {
const dispatch = useDispatch();
const handleOpenInfoModal = (title, description) => {
dispatch(openModal({title, description}))
}
return(
<div>
<button onClick={() => handleOpenInfoModal("the info modal", "some description to display in the modal body")}>
More Info
</button>
</div>
)
}
更新
要传递自定义方法和函数,ModalCompnent
您可以使用一种棘手的方法:
里面ModalComponent
:
const dispatch = useDispatch();
handleOnclose = () => {
dispatch({tye: onCloseAction})
}
hadnleOpenClose = () => {
dispatch({type: onOpenAction})
}
return(
<div>
<p>{title}</p>
<p>{description}</p>
<button onClick={handleOnClose}> CLOSE </button>
<button onClick={handleOnOpen}> OPEN </button>
// ...
)
解释:
onCloseAction
and 和onOpenAction
title 和description 一样,都是字符串,但是他们得到了action 的名字并且dispatch 了。由于您无法对商店中的功能进行消毒,因此您可以保存作为字符串的操作名称来解决问题。
推荐阅读
- vb.net - 从 ToolStripMenuItem_Click 的面板中捕获“发件人”
- c# - 如何以编程方式链接 Azure DevOps 中的分支和工作项
- file - 使用 MQL4 删除 Common Metatrader 文件夹中的文件夹内的文件
- performance - 如何优化 Python 代码以使用多处理生成和过滤非常大的活动 url 列表?[代码很慢]
- python - Python WebDriver - ChromeDriver.exe 不工作,要求我提供一些权限(!?)
- python - PySpark:如何将 Python UDF 应用于 PySpark DataFrame 列?
- java - Accepted as string despite being inputted as integer through nextInt()
- javascript - 将数据从 json 文件直接放入 javascript 变量
- javascript - 如何使文本内的单词可点击?
- amazon-web-services - AWS API Gateway Execution Logs to ELK