How to map encapsulated ui state in a redux store to props with react-redux?
<p>I'm having trouble figuring out how to compose ui widget reducers and react render trees in tandem, in a way that I can later map the resulting redux store for the reducers to props in the render tree using react-redux.  </p>

<p>Suppose a setup like this.  I'm trying to make a NameWidget that I can use anywhere in any app:</p>

<pre><code>NameView.jsx:
...
render() {
  return &lt;div&gt; Name: {this.props.name} &lt;/div&gt;;
}
...
</code></pre>

<p>====</p>

<pre><code>NameAction.js:
...
export const CHANGE_NAME = 'CHANGE_NAME';
...
export function changeNameAction(newName) {
  return {
    type: CHANGE_NAME,
    payload: newName,
  };
}
</code></pre>

<p>====</p>

<pre><code>NameReducer.js:

import { CHANGE_NAME } from './NameAction';

function ui(state = {name: ''}, action) {
  switch(action.type) {
    case(CHANGE_NAME):
      return Object.assign({}, state, {name: action.payload});
      break;
    default:
      return state;
  }
}

export default ui;
</code></pre>

<p>====</p>

<pre><code>NameWidget.js:

import { connect } from 'react-redux';
import { NameView } from './NameView';

const mapStateToProps = (state) =&gt; {
  return {
    name: state.name,
  };
};

const NameWidget = connect(
  mapStateToProps
)(NameView);

export default NameWidget;
</code></pre>

<p>If I use NameWidget directly I'll have no problem:</p>

<pre><code>NameApp.jsx:

import { createStore } from 'redux';
import app from './NameReducers';
let store = createStore(app);
...
function render() {
  return (
    &lt;Provider store={store}&gt;
      &lt;NameWidget/&gt;
    &lt;/Provider&gt;
  );
}
</code></pre>

<p>However, I don't see how to make this modular.  I can't actually put this Widget into anything else.  Suppose I wanted to do this:</p>

<pre><code>EncapsulatingView.jsx:
...
render() {
  return (
    &lt;div&gt;
      &lt;NameWidget/&gt;
      &lt;SomeOtherReduxWidget/&gt;
    &lt;/div&gt;
  );
}
...
</code></pre>

<p>====</p>

<pre><code>EncapsulatingReducer.js:
import { combineReducers } from 'redux'
import nameWidget from '../name/NameReducer';
import someOtherWidget from '../someOther/SomeOtherReduxWidgetReducer';

export default combineReducers({nameWidget, someOtherWidget});
</code></pre>

<p>(I expect that the remaining code including connect() and createStore() for Encapsulating* is obvious.)</p>

<p>This <strong>almost</strong> works, as long as all the actions across all encapsulated views have unique types.  But the problem is NameWidget's mapStateToProps; it needs to change from above to use a new path to its section of the store:</p>

<pre><code>...
const mapStateToProps = (state) =&gt; {
  return {
    name: state.nameWidget.name,
  };
};
...
</code></pre>

<p>And so on - depending on how ancestors combineReducers() to define their ever-grander super widgets and apps, the descendants somehow have to change how they mapStateToProps() to compensate.  This breaks encapsulation and reusability of code, and I don't see how to get around it in react-redux.  How can I define widgets by composing combineReducers(), and then map the resulting store to those widgets' props, in a way that's write-once-use-anywhere?</p>

<p>(Apropos of nothing, it seems strange that repeated combineReducers() creates a shape that's bottom up, but that mapStateToProps() seems to assume instead a top-down "absolute path" approach to looking up into that shape.)</p>