Skip to content

Instantly share code, notes, and snippets.

@w3aran
Created October 9, 2016 19:29
Show Gist options
  • Save w3aran/6b5966495e788aa8ec8c92ad162eb60f to your computer and use it in GitHub Desktop.
Save w3aran/6b5966495e788aa8ec8c92ad162eb60f to your computer and use it in GitHub Desktop.
esnextbin sketch
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>ESNextbin Sketch</title>
<!-- put additional styles and scripts here -->
</head>
<body>
<!-- put markup and other contents here -->
<div id="App"></div>
</body>
</html>
import { createStore } from 'redux'
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
// LOCAL REDUX STORE
// =================
// Actions
const SET_STORE_KEY = "SET_STORE_KEY";
const INCREMENT = "INCREMENT";
// Action Creators
const setStoreKey = (storeKeyName) => ({
type: SET_STORE_KEY, payload: { storeKeyName }
});
const increment = (storeKeyName) => ({
type: INCREMENT, meta: { storeKeyName }
});
// Reducers
const defaultReducerKeyName = "";
const defaultStoreKeyName = "default";
const defaultState = { [defaultStoreKeyName]: { value: 0 } };
const st = {
[defaultStoreKeyName]: {
formA: {
email: {
value: {
raw: "",
formatted: ""
},
blurred: false,
validators: [],
formatter: [],
messages: {
error: [],
warning: [],
success: []
},
}
}
}
}
const counter = (state = defaultState, action) => {
console.log("|------------------------------------------------------|");
console.log("state: ", JSON.stringify(state));
console.log("action: ", JSON.stringify(action));
console.log("|______________________________________________________|");
const strategy = {
[SET_STORE_KEY]: (state, action) => ({
...state,
[action.payload.storeKeyName]: defaultState[defaultStoreKeyName]
}),
[INCREMENT]: (state, action) => ({
...state,
[action.meta.storeKeyName]: {
value: state[action.meta.storeKeyName].value + 1
}
}),
default: (state, action) => state
};
return (strategy[action.type] || strategy.default)(state, action);
};
// Store
const counterStore = createStore(counter);
// High Order Component to connect store
const connectFeatureStore = ({
store, reducerKeyName = defaultReducerKeyName, storeKeyName = defaultStoreKeyName, setStoreKey, mapStateToProps, mapDispatchToProps
}) => (WrappedComponent) => {
const displayName = `connectFeatureStore(${getDisplayName(WrappedComponent)})`;
if (setStoreKey) store.dispatch(setStoreKey(storeKeyName));
class FeatureStoreContainer extends Component {
constructor(props) {
super(props);
this.state = this.stateShape();
this.unsubscribe = store.subscribe(this.handleStoreChanges.bind(this));
}
stateShape() {
const state = reducerKeyName ? store.getState()[reducerKeyName] : store.getState();
return mapStateToProps(state, storeKeyName, this.props);
}
componentWillUnmount() {
this.unsubscribe()
}
handleStoreChanges() {
this.setState(this.stateShape())
}
render() {
return (
<WrappedComponent
{...this.props}
{...this.state}
{...mapDispatchToProps(store.dispatch, storeKeyName, this.props)}
/>
);
}
}
FeatureStoreContainer.displayName = displayName;
return FeatureStoreContainer;
};
function getDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || "Component";
}
const mapStateToProps = (state, storeKeyName, props) => ({
value: state[storeKeyName].value
});
const mapDispatchToProps = (dispatch, storeKeyName, props) => ({
onSubmit: () => dispatch(increment(storeKeyName))
});
// PURE PRESENTATIONAL COMPONENTS
// ============================
// features/counter/components/counter-a.js
const FormAView = ({ value, onSubmit }) => (
<div>
<label>
<span>Email:</span>
<input type="text" value={value} placeholder="[email protected]" />
</label>
<button onClick={onSubmit}>Subscribe Newsletter</button>
</div>
);
const FormA = connectFeatureStore({
store: counterStore, storeKeyName: "formA", setStoreKey, mapStateToProps, mapDispatchToProps
})(FormAView);
// features/counter/components/counter-b.js
const FormBView = ({ value, onSubmit }) => (
<div>
<label>
<span>Email:</span>
<input type="text" value={value} placeholder="[email protected]" />
</label>
<button onClick={onSubmit}>Subscribe Newsletter</button>
</div>
);
const FormB = connectFeatureStore({
store: counterStore, storeKeyName: "formB", setStoreKey, mapStateToProps, mapDispatchToProps
})(FormBView);
const App = () => (
<div>
<FormA />
<hr />
<FormB />
</div>
);
ReactDOM.render(
<App />,
document.getElementById("App")
);
{
"name": "react-form-with-local-redux-store",
"version": "0.0.1",
"dependencies": {
"redux": "3.6.0",
"react": "15.3.2",
"react-dom": "15.3.2",
"babel-runtime": "6.11.6"
}
}
'use strict';
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _extends4 = require('babel-runtime/helpers/extends');
var _extends5 = _interopRequireDefault(_extends4);
var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _redux = require('redux');
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// LOCAL REDUX STORE
// =================
// Actions
var SET_STORE_KEY = "SET_STORE_KEY";
var INCREMENT = "INCREMENT";
// Action Creators
var setStoreKey = function setStoreKey(storeKeyName) {
return {
type: SET_STORE_KEY, payload: { storeKeyName: storeKeyName }
};
};
var increment = function increment(storeKeyName) {
return {
type: INCREMENT, meta: { storeKeyName: storeKeyName }
};
};
// Reducers
var defaultReducerKeyName = "";
var defaultStoreKeyName = "default";
var defaultState = (0, _defineProperty3.default)({}, defaultStoreKeyName, { value: 0 });
var st = (0, _defineProperty3.default)({}, defaultStoreKeyName, {
formA: {
email: {
value: {
raw: "",
formatted: ""
},
blurred: false,
validators: [],
formatter: [],
messages: {
error: [],
warning: [],
success: []
}
}
}
});
var counter = function counter() {
var _strategy;
var state = arguments.length <= 0 || arguments[0] === undefined ? defaultState : arguments[0];
var action = arguments[1];
console.log("|------------------------------------------------------|");
console.log("state: ", (0, _stringify2.default)(state));
console.log("action: ", (0, _stringify2.default)(action));
console.log("|______________________________________________________|");
var strategy = (_strategy = {}, (0, _defineProperty3.default)(_strategy, SET_STORE_KEY, function (state, action) {
return (0, _extends5.default)({}, state, (0, _defineProperty3.default)({}, action.payload.storeKeyName, defaultState[defaultStoreKeyName]));
}), (0, _defineProperty3.default)(_strategy, INCREMENT, function (state, action) {
return (0, _extends5.default)({}, state, (0, _defineProperty3.default)({}, action.meta.storeKeyName, {
value: state[action.meta.storeKeyName].value + 1
}));
}), (0, _defineProperty3.default)(_strategy, 'default', function _default(state, action) {
return state;
}), _strategy);
return (strategy[action.type] || strategy.default)(state, action);
};
// Store
var counterStore = (0, _redux.createStore)(counter);
// High Order Component to connect store
var connectFeatureStore = function connectFeatureStore(_ref) {
var store = _ref.store;
var _ref$reducerKeyName = _ref.reducerKeyName;
var reducerKeyName = _ref$reducerKeyName === undefined ? defaultReducerKeyName : _ref$reducerKeyName;
var _ref$storeKeyName = _ref.storeKeyName;
var storeKeyName = _ref$storeKeyName === undefined ? defaultStoreKeyName : _ref$storeKeyName;
var setStoreKey = _ref.setStoreKey;
var mapStateToProps = _ref.mapStateToProps;
var mapDispatchToProps = _ref.mapDispatchToProps;
return function (WrappedComponent) {
var displayName = 'connectFeatureStore(' + getDisplayName(WrappedComponent) + ')';
if (setStoreKey) store.dispatch(setStoreKey(storeKeyName));
var FeatureStoreContainer = function (_Component) {
(0, _inherits3.default)(FeatureStoreContainer, _Component);
function FeatureStoreContainer(props) {
(0, _classCallCheck3.default)(this, FeatureStoreContainer);
var _this = (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(FeatureStoreContainer).call(this, props));
_this.state = _this.stateShape();
_this.unsubscribe = store.subscribe(_this.handleStoreChanges.bind(_this));
return _this;
}
(0, _createClass3.default)(FeatureStoreContainer, [{
key: 'stateShape',
value: function stateShape() {
var state = reducerKeyName ? store.getState()[reducerKeyName] : store.getState();
return mapStateToProps(state, storeKeyName, this.props);
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.unsubscribe();
}
}, {
key: 'handleStoreChanges',
value: function handleStoreChanges() {
this.setState(this.stateShape());
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(WrappedComponent, (0, _extends5.default)({}, this.props, this.state, mapDispatchToProps(store.dispatch, storeKeyName, this.props)));
}
}]);
return FeatureStoreContainer;
}(_react.Component);
FeatureStoreContainer.displayName = displayName;
return FeatureStoreContainer;
};
};
function getDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || "Component";
}
var mapStateToProps = function mapStateToProps(state, storeKeyName, props) {
return {
value: state[storeKeyName].value
};
};
var mapDispatchToProps = function mapDispatchToProps(dispatch, storeKeyName, props) {
return {
onSubmit: function onSubmit() {
return dispatch(increment(storeKeyName));
}
};
};
// PURE PRESENTATIONAL COMPONENTS
// ============================
// features/counter/components/counter-a.js
var FormAView = function FormAView(_ref2) {
var value = _ref2.value;
var onSubmit = _ref2.onSubmit;
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'label',
null,
_react2.default.createElement(
'span',
null,
'Email:'
),
_react2.default.createElement('input', { type: 'text', value: value, placeholder: '[email protected]' })
),
_react2.default.createElement(
'button',
{ onClick: onSubmit },
'Subscribe Newsletter'
)
);
};
var FormA = connectFeatureStore({
store: counterStore, storeKeyName: "formA", setStoreKey: setStoreKey, mapStateToProps: mapStateToProps, mapDispatchToProps: mapDispatchToProps
})(FormAView);
// features/counter/components/counter-b.js
var FormBView = function FormBView(_ref3) {
var value = _ref3.value;
var onSubmit = _ref3.onSubmit;
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'label',
null,
_react2.default.createElement(
'span',
null,
'Email:'
),
_react2.default.createElement('input', { type: 'text', value: value, placeholder: '[email protected]' })
),
_react2.default.createElement(
'button',
{ onClick: onSubmit },
'Subscribe Newsletter'
)
);
};
var FormB = connectFeatureStore({
store: counterStore, storeKeyName: "formB", setStoreKey: setStoreKey, mapStateToProps: mapStateToProps, mapDispatchToProps: mapDispatchToProps
})(FormBView);
var App = function App() {
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(FormA, null),
_react2.default.createElement('hr', null),
_react2.default.createElement(FormB, null)
);
};
_reactDom2.default.render(_react2.default.createElement(App, null), document.getElementById("App"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment