我有React + Redux + Typescript应用程序,由地图,几个图表和一系列模态对话框组成(其中一个是打印表单)。 presentational and container components的组成如下。
┌──────────────────────────────────────────┐
│ app.tsx │
│ ┌─────────────────────────────────────┐ │
│ │ modalsContainer.tsx │ │
│ │ ┌────────────────────────────────┐ │ │
│ │ │ printModal.tsx │ │ │
│ │ │ ┌───────────────────────────┐ │ │ │
│ │ │ │ printFormContainer.tsx │ │ │ │
│ │ │ │ const mergeProps(...); │ │ │ │
│ │ │ └───────────────────────────┘ │ │ │
│ │ └────────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
│ ┌─────────────────────────────────────┐ │
│ │ mapContainer.tsx │ │
│ │ ┌────────────────────────────────┐ │ │
│ │ │ map.tsx │ │ │
│ │ │ private map:EsriMap │ │ │
│ │ └────────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
│ ┌─────────────────────────────────────┐ │
│ │ dashboard.tsx │ │
│ │ ┌────────────────────────────────┐ │ │
│ │ │ charts.tsx │ │ │
│ │ └────────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
└──────────────────────────────────────────┘
打印表单允许用户打印图表并映射到pdf。根据所选图表和当前地图,生成Web请求以打印报告。其逻辑设置如下const mergeProps(...);
所示:
const mergeProps = (stateProps: any, dispatchProps: any, ownProps: any): any => {
return {
fetchReport: (title: string, summary: string, includeMap: boolean) => {
if(includeMap) {
// fetch map image
// need access to mapcontainer /map / esrimap here
}
// ... fetch report ...
},
close: dispatchProps.close
};
};
这主要有用,但我还没有在报告中包含地图图像。为了生成地图的图像,我需要执行PrintTask。打印任务的一个参数是esri map对象。但是,从mergeProps我无法访问MapContainer或Map组件。如果我这样做,我可以添加Print():Promise<any>
函数来执行任务并返回图像。
我真的想避免使用全局变量。未来的其他功能也可能需要访问地图。我还想避免将组件作为道具传递到堆栈中。我读了一下context,但似乎非常不推荐。
如何将组件干净地传递到堆栈中的另一个组件?
答案 0 :(得分:2)
一些想法:
首先,将任何不可序列化的(例如组件或函数)放入Redux状态通常是一个坏主意(每https://redux.js.org/faq/organizing-state#can-i-put-functions-promises-or-other-non-serializable-items-in-my-store-state)。
其次,为什么回调逻辑目前在mergeProps
中定义?这个选项应该只是最后的后备。最好单独定义回调并将它们传递给组件。我在http://blog.isquaredsoftware.com/2016/10/idiomatic-redux-why-use-action-creators/处进行了一些讨论和示例。
接下来,我认为最简单的方法是定义一个单独的回调函数,它将所需的标志和作为EsriMap对象作为参数,并将该函数作为prop传递给Map组件