-
Star
(103)
You must be signed in to star a gist -
Fork
(8)
You must be signed in to fork a gist
-
-
Save gaearon/eeee2f619620ab7b55673a4ee2bf8400 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react' | |
import Subapp from './subapp/Root' | |
class BigApp extends Component { | |
render() { | |
return ( | |
<div> | |
<Subapp /> | |
<Subapp /> | |
<Subapp /> | |
</div> | |
) | |
} | |
} | |
// These subapps will be completely independent. | |
// | |
// They won't share data or actions, and won't see or communicate with each other. | |
// If you mix this approach with standard Redux approach of composing reducers, it | |
// will get extremely confusing so it's best if you pick just one: either your app | |
// is composed of pieces that follow Redux pattern holistically, or your app is so | |
// large and disjointed that smaller independent "subapps" make more sense. | |
// | |
// The first case is probably closer to normal web products, and the second case is | |
// closer to a "product hub", a "dashboard", or enterprise software where unrelated | |
// tools are grouped together because they're part of one package. |
// This is our subapp's root connected component. | |
// It can render more components, connected or not, below, just like normally. | |
// Usually we'd render it in <Provider> and be done with it. | |
class App extends Component { ... } | |
export default connect(mapStateToProps)(App) |
// However we don't have to call ReactDOM.render(<Provider><App /></Provider>) | |
// if we're interested in hiding the fact that it's a Redux app. | |
// | |
// Maybe we want to be able to run multiple instances of it in the same "bigger" app | |
// and keep it as a complete black box, with Redux being an implementation detail. | |
// To hide Redux behind a React API, we can wrap it in a special component that | |
// initializes the store in the constructor. This way every instance will be independent. | |
// | |
// Note that this is *not* recommended for parts of the same app that share data. | |
// But it can be useful when the bigger app has zero access to smaller apps' internals, | |
// and we'd like to keep the fact that they are implemented with Redux an implementation detail. | |
// Each component instance will have its own store, so they won't "know" about each other. | |
import React, { Component } from 'react' | |
import { Provider } from 'react-redux' | |
import reducer from './reducers' | |
import App from './App' | |
class Root extends Component { | |
constructor(props) { | |
super(props) | |
this.store = createStore(reducer) | |
} | |
render() { | |
return ( | |
<Provider store={this.store}> | |
<App /> | |
</Provider> | |
) | |
} | |
} |
@jochakovsky I think in that case I will use
createProvider
and your ownconnect
for<SubApp/>
.<SubApp/>
container will be taking selected props and actions from<BigApp/>
connect and from your sub-store with a custom one.
For example (pseudocode):import { Provider, connect } from 'react-redux'; const coreStore = createStore(coreReducers); const SubProvider = createProvider('sub'); const subStore = createStore(subReducers); const SubAppContainer = compose( withSubStore('sub')(mapSubStoreStateToProps, mapSubStoreDispatchToProps), connect(mapStateToProps, mapDispatchToProps), )(subAppView); <Provider store={coreStore}> <Router> <Route path='/sub'> // I assume that your SubApp will be loaded dynamically on route change <SubProvider store={subStore}> <SubAppContainer/> </SubProvider> </Route> </Router> </Provider>
the annoyance of using this method is that in the official redux documentation states - "You probably only need this if you are in the inadvisable position of having multiple stores".
Thanks for this nice Gist! But I wonder how to
dispatch
actions to the component's own special store? Is there a way to access thestore
-prop of the<Provider />
for each<SubApp />
(and their child-components)?
Has anyone figured this out yet?
I am using react to build components for a WordPress site. Each 'root' component will need its own state, but how would I use useDispatch and useSelector to get each component's appropriate state?
@Nathaniel-Fernandes @gaearon any advice with dispatching scoped actions?
How about using a subApp as a child of another subApp like this?
return(
<SubApp1>
<SubApp2/>
</SubApp1>
)
Suppose the SupApp2 is a calendar app or something which should be used inside of SubApp1, but there are no shared components between these 2 subApps.
Is it possible?
@jochakovsky I think in that case I will use
createProvider
and your ownconnect
for<SubApp/>
.<SubApp/>
container will be taking selected props and actions from<BigApp/>
connect and from your sub-store with a custom one.For example (pseudocode):