0
votes

Is there a way to pass some part of state (not the whole state) to the child component of some React component? So that mapStateToProps and getState method in redux middleware would use such a substate?

This is important for developing react-redux logic that is unaware of state structure it is used in. It could be then used in several app places or different applications. Such logic would behave as an independent module and satisfy the principle of encapsulation.

Such concept exist in Knockout.js ("with" operator) and in desktop WPF.NET (passing DataContext to child element).

Thank you!

1

1 Answers

0
votes

One possible approach is to use selectors and/or namespaces.

With selector, you can encapsulate the logic of querying the state object.

However, you cannot totally hide redux state's shape from your react-redux logic, since it's subscribed to the whole store, by design. Still, we can use a namespace here.

Example:

// counter.js
const namespace = 'counter'
const actualReducer = (state, action) => action.type === 'INC' ? state + 1 : state;
export default { [namespace]: actualReducer }
export const selector = (state, ownProps) => state[namespace]

// configureStore.js
import reducer from './counter'
const store = createStore(reducer)
export default store

// Component.js
import { selector } from './counter'
const Component = props => <some markup />
export default connect(selector)(Component)

So what do we have? In brief:

  1. Component.js is not aware of state shape and even the namespace;
  2. configureStore.js is not aware of the counter namespace;
  3. counter.js is the only place, that is aware of its namespace in the store.

One can also extract selector to separate file since it's the only place where we have to deal with original state object.

Note that namespace should be unique, or, to be re-usable from app to app, it can be imported or injected.


IMO, the idea of re-using react-redux stuff (i.e. connect(...)) is not very solid. Since usually, the state shape is not going to be the same from app to app

I'd encourage you to keep it explicit, so the underlying component is the real one who should have an API that is as unopinionated as possible.