Skip to content

Commit

Permalink
using store from child comp's
Browse files Browse the repository at this point in the history
  • Loading branch information
John Edward Escuyos committed Aug 1, 2017
2 parents a9b9f14 + f31c33a commit 0fddcaa
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 12 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ Create an `index.js` file under your component folder. Let's try to separate the

```js
import component from 'recomponent';
import MyComponentLogic from './MyComponentLogic';
import MyComponentTemplate from './MyComponentTemplate';
import './MyComponentStyles.css';
import MyComponentLogic from './MyComponent.js';
import MyComponentTemplate from './MyComponent.jsx';
import './MyComponent.css';

export default component({
logic: MyComponentLogic,
Expand All @@ -50,11 +50,11 @@ Wraps your logic, view, store and styles in a single whole component.
```

### Store
**recomponent** provides optional store from your component. This store is just like a state of your component. The reason why it's separated aside from using component's state itself, because we might likely to have our own stored data that has its own purpose.
**recomponent** provides optional store from your component. This store is just like a state of your component. The reason why it's separated aside from using component's state itself, because you might likely to have your own stored data provider that has its own purpose.

Use this as custom store for your specific component. Pass the store reference via `prop` to use on child components.
Use this as custom store for your specific component. If child components are also wrapped with **recomponent**, they can directly access the store from their context (`this.store` or `context.store` for dumb components).

You can use it by adding `store` in component declaration:
You can add store by adding `store` key in declaration:
```js
export default component({
...
Expand All @@ -63,7 +63,7 @@ export default component({
```

#### `this.store`
Store values from the `component` it was defined.
Stored data from the `component` it was defined.

#### `this.setStore({ key: value })`
Update store and forces the component to update.
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "recomponent",
"version": "0.0.4",
"version": "0.1.0",
"description": "Writing react components redefined",
"main": "./dist/index.js",
"scripts": {
Expand Down Expand Up @@ -44,5 +44,8 @@
"react": "^15.6.1",
"react-addons-test-utils": "^15.6.0",
"react-dom": "^15.6.1"
},
"dependencies": {
"prop-types": "^15.5.10"
}
}
40 changes: 36 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,56 @@
/* eslint-disable no-param-reassign */
function component({ logic, template, styles, store = {} }) {
import PropTypes from 'prop-types';

const storeContextTypes = {
store: PropTypes.object,
setStore: PropTypes.func,
};

function component({ logic, template, styles, store }) {
if (!template) throw new Error('template is not defined');

if (logic) {
//
if (store) {
// inject store
logic.prototype.store = store;
logic.prototype.setStore = (function (obj = {}) {
Object.keys(obj).forEach((key) => {
this.store[key] = obj[key];
this.forceUpdate();
});
});
// set store context for children
logic.childContextTypes = storeContextTypes;
logic.prototype.getChildContext = (function () {
return {
store: this.store,
setStore: this.setStore.bind(this),
};
});
} else {
// class-based child expects store from context
logic.contextTypes = storeContextTypes;
// using react hook to inject store from context
const selfWillMount = logic.prototype.componentWillMount;
logic.prototype.componentWillMount = (function () {
if (this.context.store) {
this.store = this.context.store;
this.setStore = this.context.setStore;
if (selfWillMount) selfWillMount();
}
});
}

logic.prototype.render = (function () {
return template.bind(this)({ ...this.props, ...{ styles } });
return template.call(this,
{
...this.props,
...{ styles },
});
});
} else {
template.prototype.store = store;
// function-based child expects store from context
template.contextTypes = storeContextTypes;
return template;
}

Expand Down

0 comments on commit 0fddcaa

Please sign in to comment.