当将动作调度到映射到该组件的reducer时,更新我的react组件上的props属性时遇到问题。我将解释显示代码的过程。
因此,首先,我试图在我的React组件之外分派动作(从Electron菜单项click中触发的分派)。
这是分派操作的菜单服务功能。如果我们要console.log(store.getState())
在分派后执行此操作,我们将正确看到商店状态中的消息:
dispatchMessage(): void {
let message = messageService.getMessage();
let store = StoreProvider.getInstance().store;
store.dispatch(loadMessage(message));
}
请注意,StoreProvider正在获取Redux商店的实例,这是完成的,因为代码不在React组件的范围内,这是StoreProvider.ts:
import { createStore } from 'redux';
import allReducers from '../reducers/index';
export default class StoreProvider {
private static _instance: StoreProvider;
store: any = null;
constructor() {
this.store = createStore(
allReducers
);
}
public static getInstance(): StoreProvider {
return StoreProvider._instance || (StoreProvider._instance = new StoreProvider());
}
}
这是我的index.tsx文件,我在其中引导应用程序组件并使用相同的商店提供程序加载商店(这将填充StoreProvider的新实例,构造函数将在菜单项中设置以后可以访问的商店)点击):
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import allReducers from './reducers/index';
import App from './app';
import StoreProvider from './providers/store-provider';
const bootstrapperElement: HTMLElement = document.getElementById('app') as HTMLElement;
const store = StoreProvider.getInstance().store;
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
bootstrapperElement);
好的,这就是将事情连接到要分派动作的地方。因此,当我在菜单服务功能中调度动作时,它正在调用此动作:
export const loadMessage = (message: any) => {
return {
type: 'MESSAGE_LOADED',
payload: message
};
};
一旦分派了动作,该减速器就会将其拾取。请注意console.log(action.payload)
,此时,它将正确记录从菜单服务发送的消息,并且我可以看到期望的内容,到目前为止,它似乎仍在工作。
export default (state: any = null, action: any) => {
switch (action.type) {
case 'MESSAGE_LOADED':
console.log(action.payload);
return action.payload;
default:
return state;
}
};
这是将该状态映射到prop的组件:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
class SideMenu extends Component<any> {
render() {
return (
<div>
<h2 onClick={ () => console.log(this.props.fileExplorer)}>Test</h2>
</div>
);
}
}
const mapStateToProps = (state: any) => {
return {
fileExplorer: state.fileExplorer
};
};
export default connect<any>(mapStateToProps, {})(SideMenu);
因此,当我单击带有文本“ TEST”的h2元素时,我总是得到null,这是最初传递给接收该消息的reducer的默认值(即使上面我们知道控制台中的console.log从菜单服务分派操作时,reducer确实在打印正确的值)。
这也是我要添加到商店的减速器:
import { combineReducers } from 'redux';
import FileExplorerReducer from './file-explorer';
const allReducers = combineReducers({
fileExplorer: FileExplorerReducer
});
export default allReducers;
在这个问题上的任何帮助将不胜感激。我相信此刻,我倾向于将它作为StoreProvider的问题,并且可能会有两个单独的商店实例?即使减速器返回action.payload并且商店的fileExplorer状态已更新(至少从分派后的菜单服务检查中),也不太确定为什么组件this.props.fileExplorer总是为null。
根据接受的答案更改为回答上述问题:
因此,必须允许IPC(进程间通信),我们必须在菜单服务中从BrowserWindow.webContents.send()发布消息,如下所示:
let message = let message = messageService.getMessage();
BrowserWindow.getFocusedWindow().webContents.send('dispatch-action', { payload: { message});
然后在Store Provider中,我在构造函数中添加了订户,以便Store实例可以接收来自渲染器进程中主进程发布的消息,如下所示:
import { ipcRenderer } from 'electron';
export default class StoreProvider {
private static _instance: StoreProvider;
store: any = null;
constructor() {
this.store = createStore(
allReducers
);
ipcRenderer.on('dispatch-action', (event: any, arg: any) => {
this.store.dispatch(loadMessage(arg.payload));
});
}
public static getInstance(): StoreProvider {
return StoreProvider._instance || (StoreProvider._instance = new StoreProvider());
}
}
我不能完全确定,但是基于您的描述,您试图在Electron的菜单事件上执行,所以我建议您检查一下正在分派菜单事件的进程。如果托管渲染组件的不是渲染器进程,则可能会看到每个不同的进程都有隔离的存储状态,可能需要存储同步中间件来进行redux或将IPC调用到渲染器进程中,然后让渲染器直接为渲染器端的redux存储调度动作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句