Skip to content

Commit f731513

Browse files
committed
UPDATE: removing separate declaration for hooks and handlers
1 parent d79cd56 commit f731513

13 files changed

+593
-120
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ yarn-debug.log*
66
yarn-error.log*
77

88
/dist
9+
/packages
910
package-lock.json
1011
*.map
1112
.npmrc

README.md

Lines changed: 88 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,26 @@
22

33
hoc provide a simple apis to create javascript reusable components. It provide an abstraction from underlying framework, helps reuse the same component for different libraries with minimum code changes.
44

5-
# Install
5+
## Install
66

77
```
88
npm i -S @js-factory/hoc
9+
910
```
1011

11-
# features!
12-
- Allow you to maximize vanilla javascript use
13-
- Promotes function programming by exposting functions/methods outside the class
12+
## Motivation
13+
Modern frontend applications are getting complex day by day. It has to manage core business logic, even more complex layouts, and data. This is extremely important that frontend application architecture follows core software design principles.
14+
15+
### Separation of concern
16+
17+
In [computer science](https://en.wikipedia.org/wiki/Computer_science), separation of concerns (SoC) is a design principle for separating a computer program into distinct sections, such that each section addresses a separate [concern](https://en.wikipedia.org/wiki/Concern_%28computer_science%29).
1418

19+
20+
## Getting Started
1521
```js
1622
// ExampleComponent.js
1723

18-
import { withPreact as component } from '@js-factory/hoc';
24+
import { withPreact as withState } from '@js-factory/hoc';
1925
import componentDidMount from './hooks/afterRender';
2026
import componentShouldUpdate from './hooks/afterUpdate';
2127
import componentWillMount from './hooks/beforeRender';
@@ -33,62 +39,98 @@ const instanceProps = {
3339
counter: 0
3440
};
3541

36-
@component({
42+
@withState({
3743
state,
3844
instanceProp,
39-
hooks: {
40-
componentDidMount,
41-
componentWillMount,
42-
componentWillUpdate,
43-
componentWillUnmount,
44-
componentShouldUpdate
45-
},
46-
eventHandler: {
47-
onClickHanlder,
48-
onScrollHanlder
49-
},
45+
componentDidMount,
46+
componentWillMount,
47+
componentWillUpdate,
48+
componentWillUnmount,
49+
componentShouldUpdate,
50+
onClickHanlder,
51+
onScrollHanlder,
5052
template: ExampleComponentTmpl
5153
})
5254
export default class ExampleComponent {}
5355
```
56+
5457
```js
5558
// ExampleComponentTmpl.js
5659
// This is preact functional component
5760

58-
import {h} from 'preact';
61+
import { h } from 'preact';
5962

6063
const ExampleComponentTmpl = (props) => {
61-
const { getState, onClickHander } = props;
62-
const {salutation} = getState();
64+
const { state, instanceProp, onClickHander } = props;
65+
const { salutation } = state;
6366
return(
6467
<div>
65-
<p> {salutation} customer! </p>
68+
<p> {salutation} user! </p>
6669
<button onClick={onClickHander}>Say Hello </button>
6770
</div>
6871
);
6972
}
7073
```
7174

75+
## Overview
76+
`HOC` offers four major components e.g. `state`, `template`, `instanceProps`, `methods`.
77+
7278
### state
73-
**state** is component local state. It can be modified with `setState` function. Every call to `setState` will cause component re-rending. In case you do not want render the component every time state changes, please use instanceProp.
79+
The state is a plain JavaScript object that represents your component local state. Please read about [React state](https://reactjs.org/docs/state-and-lifecycle.html) if you are not aware about what a component state is all about. `hoc` exposes a it's own `setState` to update component state.
7480

75-
In order to access application state you need to use `getState` method.
81+
```js
82+
const state = {
83+
...
84+
count: 0,
85+
...
86+
};
7687

77-
### instanceProp
78-
**instanceProp** is same as *state* but it offers its own getter `getInstanceProp` and setter `setInstanceProp`. instanceProp changes do not call `render`.
88+
const increment = ({ state, state }) => {
89+
const { count } = state;
90+
return state({
91+
count: count + 1
92+
});
93+
};
94+
```
95+
96+
### instanceProps
97+
The instanceProps is same as *state* unlike state any update to it will not trigger component re-rendering. You can update instanceProps using `setInstanceProps` method.
98+
99+
```js
100+
const instanceProps = {
101+
...
102+
count: 0,
103+
...
104+
};
79105

80-
### hooks
106+
const increment = ({ instanceProps, setInstanceProps }) => {
107+
const { count } = instanceProps;
108+
return setInstanceProps({
109+
count: count + 1
110+
});
111+
};
112+
113+
```
114+
115+
### template
116+
A template is functional component represents presentation layer.
117+
118+
### methods
119+
You can add as many functions as you need to manage your component state and handle user interactions. These methods could be lifecycle hooks of underlying framework like componentDidMount, componentWillUpdate or simple event handlers.
120+
121+
#### life cycle hooks
81122
hoc allows developer to use underlying library hooks like componentDidMount, componentWillMount etc. Please refer above component definition.
82123

83-
**Note:** Unlike react or preact you will not have access to `this`. You will get all the handlers, action, state as a props.
124+
**Note:** Unlike react or preact you will not have access to `this`. `hoc` will inject all component properties and methods in run time.
84125

85126

86-
### eventHandler
87-
**eventHandler** is a collection of dom event handlers i.e. click, scroll, mouseover etc. Event handlers are plain javascript functions and surely not tightely coupued with any underlying library.
127+
#### event handlers
128+
You can define any dom event handler and bind it with component. Event handlers are plain javascript functions and surely not tightly coupled with any underlying library.
129+
88130
```js
89131
const onClickHandler = (props, e) => {
90132
e.preventDefault();
91-
const { getState, setState, getInstanceProp } = props;
133+
const { state, setState, getInstanceProp } = props;
92134
const state = getState();
93135
return setState({
94136
...state,
@@ -97,7 +139,21 @@ const onClickHandler = (props, e) => {
97139
}
98140
```
99141

100-
### template
101-
**template** represents presentation layer. Mostly it's html is going to rendered in the browser.
142+
**props** contains component state, methods etc.
143+
**e** is a dom event instance.
144+
145+
#### Other methods
146+
Usually any component has a lot of helper methods. You can define these method as part of component definition.
147+
148+
```js
149+
function foo(props, ...args){
150+
// function body goes here
151+
}
152+
```
153+
154+
**props** contains component state, methods etc.
155+
**...args** are runtime arguments supplied
156+
157+
102158

103159

example/preact/ExamplePage.js

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,45 @@
1-
import { h } from 'preact';
2-
import { withPreact as component } from '@js-factory/hoc';
1+
import { Component } from '@js-factory/hoc';
2+
import ExampleTmpl from './ExampleTmpl';
33

4-
@component({
5-
hooks: {
6-
componentWillMount() {
7-
console.log('before render');
8-
},
9-
componentDidMount({ sayHello }) {
10-
console.log('afterRender');
11-
}
4+
@Component({
5+
componentWillMount({ state }) {
6+
console.log('before render', state.x);
7+
},
8+
componentDidMount({ state }) {
9+
console.log('after Render', state.x);
10+
},
11+
componentDidUpdate({ state }) {
12+
console.log('after Update', state.x);
1213
},
1314
state: {
14-
x: 1,
15+
z: 100,
16+
x: 1
1517
},
1618
instanceProps: {
19+
z: 100,
1720
y: 1
1821
},
19-
eventHandlers: {
20-
onClickHandler({ getState, onClickAction, setState, getInstanceProps, setInstanceProps }) {
21-
const { y } = getInstanceProps();
22-
const { x } = getState();
23-
setInstanceProps({ y: y + 1 });
24-
setState({ x: x + 1 });
25-
}
22+
sayHello({ state }, name, date) {
23+
const { x } = state;
24+
console.log(`x - ${x}`);
25+
console.log(`Hello ${name} : ${date}`);
2626
},
27-
template: (props) => {
28-
const { getState, onClickHandler, getInstanceProps, state } = props;
29-
console.log('state', getState());
30-
console.log('instance prop', getInstanceProps())
27+
onClickHandler(props, e) {
28+
e.preventDefault();
29+
const {
30+
getState,
31+
onClickAction,
32+
setState,
33+
getInstanceProps,
34+
setInstanceProps,
35+
sayHello
36+
} = props
37+
const { y } = getInstanceProps();
3138
const { x } = getState();
32-
return (
33-
<div>
34-
<h1>Example Page</h1>
35-
<button onClick={onClickHandler}>Increment</button>
36-
<p>state - {x}</p>
37-
<p>ip - {getInstanceProps().y}</p>
38-
</div>
39-
);
40-
}
39+
setInstanceProps({ y: y + 1 });
40+
setState({ x: x + 1 });
41+
sayHello('Foo', Date.now());
42+
},
43+
template: ExampleTmpl
4144
})
4245
export default class ExamplePage { }

example/preact/ExampleTmpl.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { h } from 'preact';
2+
3+
const ExampleTmpl = (props) => {
4+
const { state, onClickHandler, instanceProps } = props;
5+
console.log('state', state);
6+
console.log('instance prop', instanceProps);
7+
const { x } = state;
8+
return (
9+
<div>
10+
<h1>Example Page</h1>
11+
<button onClick={onClickHandler}>Increment</button>
12+
<p>state - {x}</p>
13+
<p>ip - {instanceProps.y}</p>
14+
</div>
15+
);
16+
};
17+
18+
export default ExampleTmpl;

example/preact/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"main": "webpack.config.js",
33
"scripts": {
44
"ex": "webpack --mode production --watch --progress",
5-
"server": "webpack-dev-server --open"
5+
"start": "webpack-dev-server --open"
66
},
77
"dependencies": {
88
"@js-factory/hoc": "0.0.3",

integration/index.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1-
import withPreact from './preact/component';
1+
import Component from './preact/component_v2';
22

3-
export { withPreact };
3+
const withState = Component;
4+
5+
export {
6+
withState,
7+
Component
8+
};
9+
10+
export default Component;

integration/preact/.babelrc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"presets": [
3+
"env",
4+
"preact"
5+
],
6+
"plugins": [
7+
"transform-decorators-legacy",
8+
"transform-class-properties",
9+
[
10+
"transform-object-rest-spread",
11+
{
12+
"useBuiltIns": true
13+
}
14+
],
15+
[
16+
"transform-react-jsx",
17+
{
18+
"pragma": "h"
19+
}
20+
]
21+
]
22+
}

integration/preact/.npmignore

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
8+
*.map
9+
.npmrc
10+
11+
# Runtime data
12+
pids
13+
*.pid
14+
*.seed
15+
*.pid.lock
16+
17+
# Directory for instrumented libs generated by jscoverage/JSCover
18+
lib-cov
19+
20+
# Coverage directory used by tools like istanbul
21+
coverage
22+
23+
# nyc test coverage
24+
.nyc_output
25+
26+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
27+
.grunt
28+
29+
# Bower dependency directory (https://bower.io/)
30+
bower_components
31+
32+
# node-waf configuration
33+
.lock-wscript
34+
35+
# Compiled binary addons (https://nodejs.org/api/addons.html)
36+
build/Release
37+
38+
# Dependency directories
39+
node_modules/
40+
jspm_packages/
41+
42+
# TypeScript v1 declaration files
43+
typings/
44+
45+
# Optional npm cache directory
46+
.npm
47+
48+
# Optional eslint cache
49+
.eslintcache
50+
51+
# Optional REPL history
52+
.node_repl_history
53+
54+
# Output of 'npm pack'
55+
*.tgz
56+
57+
# Yarn Integrity file
58+
.yarn-integrity
59+
60+
# dotenv environment variables file
61+
.env
62+
63+
# next.js build output
64+
.next

0 commit comments

Comments
 (0)