gpt4 book ai didi

javascript - Redux reducer 没有从 React 组件外部的调度更新 React 组件中的 prop 值

转载 作者:行者123 更新时间:2023-11-30 20:53:09 25 4
gpt4 key购买 nike

当一个 Action 被分派(dispatch)到映射到该组件的缩减器时,我在更新我的 React 组件上的 props 属性时遇到了问题。我将在显示代码的过程中进行解释。

所以首先,我尝试在我的 React 组件之外调度操作(调度从 Electron 菜单项点击触发)。

这是调度操作的菜单服务函数。如果我们在发送后执行 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 文件,我在其中引导 App 组件并使用相同的商店提供程序加载商店(这将填充 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);

好的,这就是事情如何连接到分派(dispatch) Action 的地方。所以当我在菜单服务函数中发送我的 Action 时,它调用了这个 Action :

export const loadMessage = (message: any) => {
return {
type: 'MESSAGE_LOADED',
payload: message
};
};

一旦 action 被分派(dispatch),它就会被这个 reducer 拾取。注意 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;
}
};

这是将该状态映射到 props 的组件:

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 的默认值(即使在上面我们知道控制台。当从菜单服务调度操作时,reducer 确实打印了正确的值。

这也是我要添加到商店的 reducer :

import { combineReducers } from 'redux';

import FileExplorerReducer from './file-explorer';

const allReducers = combineReducers({
fileExplorer: FileExplorerReducer
});

export default allReducers;

在此问题上的任何帮助将不胜感激。我相信此刻我倾向于它是 StoreProvider 的问题并且可能有 2 个独立的商店实例?不太确定为什么组件 this.props.fileExplorer 始终为 null,即使 reducer 返回 action.payload 并且商店的 fileExplorer 状态已更新(至少在调度后检查菜单服务)。

根据已接受的答案更改为回答上述问题:

因此必须允许 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 的菜单事件执行,我想建议检查你正在调度菜单事件的进程。如果您托管 React 组件的不是渲染器进程,您可能会看到每个不同的进程都有独立的存储状态,可能需要用于 redux 的存储同步中间件,或者将 IPC 调用到渲染器进程中,然后让渲染器直接为渲染器端 redux 存储分派(dispatch)操作。

关于javascript - Redux reducer 没有从 React 组件外部的调度更新 React 组件中的 prop 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47949841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com