title: Redux reducer not updating prop value in React component from dispatch outside React components
body: <p>I am having an issue with updating my props property on my react component when an action is dispatched to a reducer that is mapped to that component.  I will explain along the way showing code.</p>
  
  <p>So first off, I am trying to dispatch the action outside of my react components (dispatch fired from Electron menu item click).</p>
  
  <p>This is the menu service function that is dispatching the action.  If we were to do <code>console.log(store.getState())</code> after the dispatch, we would see the message in the store's state correctly:</p>
  
  <pre><code>dispatchMessage(): void {
      let message = messageService.getMessage();
      let store = StoreProvider.getInstance().store;
      store.dispatch(loadMessage(message));
  }
  </code></pre>
  
  <p>Notice the StoreProvider getting an instance of the Redux store, this is being done because the code is outside the scope of the React components, this is the StoreProvider.ts:</p>
  
  <pre><code>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());
      }
  }
  </code></pre>
  
  <p>This is my index.tsx file where I bootstrap the App component and load the store in using the same store provider (This will populate the new instance of the StoreProvider, where the constructor will set the store that I can access later in the menu item click):</p>
  
  <pre><code>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(
      &lt;Provider store={store}&gt;
          &lt;App /&gt;
      &lt;/Provider&gt;,
      bootstrapperElement);
  </code></pre>
  
  <p>Ok so this is how things are wired up to the point of where the action is being dispatched.  So when I dispatch my action in the menu service function, it is calling this action:</p>
  
  <pre><code>export const loadMessage = (message: any) =&gt; {
      return {
          type: 'MESSAGE_LOADED',
          payload: message
      };
  };
  </code></pre>
  
  <p>Once the action is dispatched it is picked up by this reducer. Notice the <code>console.log(action.payload)</code>, at this point it will log the message that was dispatched from the menu service correctly and I can see the content that is expected, seems to be working so far.</p>
  
  <pre><code>export default (state: any = null, action: any) =&gt; {
      switch (action.type) {
      case 'MESSAGE_LOADED':
          console.log(action.payload);
          return action.payload;
      default:
          return state;
      }
  };
  </code></pre>
  
  <p>This is the component that is mapping that state to props:</p>
  
  <pre><code>import React, { Component } from 'react';
  import ReactDOM from 'react-dom';
  import { bindActionCreators } from 'redux';
  import { connect } from 'react-redux';
  
  class SideMenu extends Component&lt;any&gt; {
      render() {
          return (
              &lt;div&gt;
                  &lt;h2 onClick={ () =&gt; console.log(this.props.fileExplorer)}&gt;Test&lt;/h2&gt;
              &lt;/div&gt;
          );
      }
  }
  
  const mapStateToProps = (state: any) =&gt; {
      return {
          fileExplorer: state.fileExplorer
      };
  };
  
  export default connect&lt;any&gt;(mapStateToProps, {})(SideMenu);
  </code></pre>
  
  <p>So when I click the h2 element with the text 'TEST', I am always getting null, which is the default value that was originally passed into that reducer that is picking up that message (Even though above we know the console.log in the reducer is indeed printing the correct value when the action is dispatched from the menu service).</p>
  
  <p>Also this is my reducers that I am adding to the store:</p>
  
  <pre><code>import { combineReducers } from 'redux';
  
  import FileExplorerReducer from './file-explorer';
  
  const allReducers = combineReducers({
      fileExplorer: FileExplorerReducer
  });
  
  export default allReducers;
  </code></pre>
  
  <p>Any assistance in this issue will be greatly appreciated.  I believe at this moment I am leaning towards it being an issue with the StoreProvider and there possibly being 2 seperate instances of the store?  Not quite sure why the component this.props.fileExplorer is always null even though the reducer returns the action.payload and the fileExplorer state of the store is updated (at least from checking in the menu service after the dispatch).</p>
  
  <p><strong>Changes to answer the above question according to the accepted answer:</strong></p>
  
  <p>So having to allow IPC (Inter Process Communication), we had to publish the message from the BrowserWindow.webContents.send() in the menu service like so:</p>
  
  <pre><code>let message = let message = messageService.getMessage();
  BrowserWindow.getFocusedWindow().webContents.send('dispatch-action', { payload: { message});
  </code></pre>
  
  <p>And then in the Store Provider, I added the subscriber in the constructor so the instance of the store could receive the message published from the main process in the renderer process like so:</p>
  
  <pre><code>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) =&gt; {
              this.store.dispatch(loadMessage(arg.payload));
          });
      }
  
      public static getInstance(): StoreProvider {
          return StoreProvider._instance || (StoreProvider._instance = new StoreProvider());
      }
  }
  </code></pre>