Redux Reducer不会从React组件外部的调度更新React组件中的prop值

肖恩

当将动作调度到映射到该组件的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());
    }
}
OJ权

我不能完全确定,但是基于您的描述,您试图在Electron的菜单事件上执行,所以我建议您检查一下正在分派菜单事件的进程。如果托管渲染组件的不是渲染器进程,则可能会看到每个不同的进程都有隔离的存储状态,可能需要存储同步中间件来进行redux或将IPC调用到渲染器进程中,然后让渲染器直接为渲染器端的redux存储调度动作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章