Skip to content

Commit

Permalink
implement isolation of UserCreator widget with nested stores
Browse files Browse the repository at this point in the history
  • Loading branch information
rikukissa committed Aug 30, 2017
1 parent 8feb737 commit 6d4887e
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 10 deletions.
16 changes: 11 additions & 5 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ import React, { Component } from "react";
import UserCreator from "./UserCreator";
import { connect } from "react-redux";

import { userCreated } from "./state/users";

class App extends Component {
render() {
const { users } = this.props;
const { users, createUser } = this.props;
return (
<div>
<UserCreator />
<UserCreator />
<UserCreator />
<UserCreator onUserCreated={createUser} id="userCreator1" />
<UserCreator onUserCreated={createUser} id="userCreator2" />
<UserCreator onUserCreated={createUser} id="userCreator3" />
<div id="userList">
{users.map(({ name }) =>
<div key={name} className="user">
Expand All @@ -28,4 +30,8 @@ function mapStateToProps(state) {
};
}

export default connect(mapStateToProps)(App);
const mapDispatchToProps = {
createUser: userCreated
};

export default connect(mapStateToProps, mapDispatchToProps)(App);
42 changes: 39 additions & 3 deletions src/UserCreator/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
import React, { Component } from "react";
import { updateNameField, createUser } from "./actions";
import { connect } from "react-redux";
import reducer from "./reducer";

import { connect, Provider } from "react-redux";
import { createStore } from "redux";

function isolate(WrappedComponent) {
return class Widget extends Component {
constructor(props) {
super(props);
this.displayName = props.id;
this.store = createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__({ name: props.id })
);
}
render() {
return (
<Provider store={this.store}>
<WrappedComponent {...this.props} />
</Provider>
);
}
};
}

class UserCreator extends Component {
updateNameField = event => {
Expand All @@ -10,6 +34,14 @@ class UserCreator extends Component {
event.preventDefault();
this.props.createUser();
};

componentWillReceiveProps(nextProps) {
const { createdUser } = nextProps;
if (createdUser && !this.props.createdUser) {
this.props.onUserCreated(createdUser);
}
}

render() {
const { name } = this.props;
return (
Expand All @@ -22,10 +54,14 @@ class UserCreator extends Component {
}
}

const mapStateToProps = state => ({ name: state.name });
const mapStateToProps = state => ({
name: state.name,
createdUser: state.createdUser
});

const mapDispatchToProps = {
updateNameField: updateNameField,
createUser: createUser
};

export default connect(mapStateToProps, mapDispatchToProps)(UserCreator);
export default isolate(connect(mapStateToProps, mapDispatchToProps)(UserCreator));
8 changes: 6 additions & 2 deletions src/UserCreator/reducer.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { UPDATE_NAME_FIELD } from "./actions";
import { UPDATE_NAME_FIELD, CREATE_USER } from "./actions";

const initialState = {
name: ""
name: "",
// Only way of getting the information back to the component..
createdUser: null
};

export default function(state = initialState, action) {
switch (action.type) {
case UPDATE_NAME_FIELD:
return { ...state, name: action.payload };
case CREATE_USER:
return { ...state, createdUser: { name: state.name } };
default:
return state;
}
Expand Down

0 comments on commit 6d4887e

Please sign in to comment.