如何将反应组分干净地传递到组件层中深处的另一个组件?

时间:2017-01-09 22:00:20

标签: reactjs typescript redux react-redux

我有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,但似乎非常不推荐。

如何将组件干净地传递到堆栈中的另一个组件?

1 个答案:

答案 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组件