Skip to content

Commit 0ef5376

Browse files
committed
docs
1 parent 0a5b16a commit 0ef5376

File tree

6 files changed

+139
-111
lines changed

6 files changed

+139
-111
lines changed

README.md

Lines changed: 128 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -2,117 +2,37 @@
22

33
`fuse-react` is an abtraction on top of React Component which relieves the pain for those who find Redux overly complicated.
44

5-
The concept is simple and revolves around a global Store object that is accessible by all components.
6-
A component can "connect" to an individual key in the store and react to its changes.
7-
8-
9-
The framework also offers a router which has some improvements comparing to `react-router`
10-
11-
```tsx
12-
@connect("count")
13-
class MyUser extends Fusion<any, any, MyStore> {
14-
public render() {
15-
return (
16-
<div>{this.store.count}</div>
17-
);
18-
};
19-
}
20-
```
21-
22-
The decorator `@connect` registers subscription to the store, therefore once we update the object it will be forced to get updated.
23-
24-
```ts
25-
dispatch("count", 1); // like this
26-
dispatch({count : 1}); // or like this
27-
```
28-
29-
## Create your store
30-
31-
```ts
32-
import { createStore } from "fuse-react";
33-
class MyStore {
34-
count = 0;
35-
}
36-
createStore(MyStore);
37-
```
38-
39-
A class will be instantiated and registered globally
40-
41-
## Connecting
42-
43-
A component can be connected to individual keys in the store
44-
```tsx
45-
import { connect } from "fuse-react";
46-
@connect("count", "user")
47-
class MyUser extends Fusion<any, any, MyStore> {
48-
public render() {
49-
return (
50-
<div>{this.store.count}</div>
51-
);
52-
};
53-
}
54-
```
555

56-
The third (optional) generic typing will help with your typings on `this.store`, meanwhile the first and the second arguments remain conventional(IProps, IState)
57-
58-
### Connecting with deep compare
59-
60-
There are situations where you would like to avoid unnesserary updates. For that preffix your key with `@`
61-
62-
```ts
63-
import { connect } from "fuse-react";
64-
@connect("@user")
65-
class MyUser extends Fusion<any, any, MyStore> {
66-
public render() {
67-
return (
68-
<div>{this.store.user.name}</div>
69-
);
70-
};
71-
}
72-
```
6+
The concept is simple and revolves around a global Store object that is accessible by all components.
737

74-
Once the dispatcher recieves an event and goes through all subscriptions it will check if the new value is different from the one in the store.
8+
`fuse-react` offers a solution to react routing which is more flexible and memory efficient than `react-router-dom`
759

76-
### Init
7710

78-
```tsx
79-
@connect("count", "user")
80-
class MyUser extends Fusion<any, any, MyStore> {
81-
private init(){}
82-
public render() {
83-
return (
84-
<div>{this.store.count}</div>
85-
);
86-
};
87-
}
88-
```
8911

90-
It's important to understand the `init` of the component, it will be triggered on `componentWillMount` and `componentWillReceiveProps` as well as when a subscription key in the store has been changed.
12+
## Router
9113

92-
Avoid dispatching events from `init` as it might cause an infinite loop.
14+
FuseReact Router is very similar to `react-router`, in fact it mimics the API so the transition will be as smooth as possible.
9315

94-
### Dispatch
16+
![diagram](diagram.png)
9517

96-
```tsx
97-
import { dispatch } from "fuse-react";
98-
dispatch("count", 1); // like this
99-
dispatch({count : 1}); // or like this
100-
```
18+
Unlike `react-router` `fuse-react router` subscribes to changes and renders only necessary components avoiding `render` from the top of the DOM tree.
10119

10220

103-
## Router
21+
Features:
10422

105-
FuseReact Router is very similar to `react-router`, in fact it mimics the API so the transition will be as smooth as possible.
23+
* Memory efficient (render only required component)
24+
* Extended Link support (a mini router)
25+
* No wrapping the application
26+
* Nothing else is required but `Switch` and `Route` (works with any React.Component framework)
10627

10728
### Switch and Route
10829
To create a router swith do the following
10930

11031
```tsx
11132
import * as React from "react";
112-
import { Fusion, Switch, Route } from "fuse-react";
33+
import { Switch, Route } from "fuse-react";
11334

114-
export class UserRoute extends Fusion<any, any, MyStore> {
115-
init() { }
35+
export class UserRoute extends React.Component {
11636
public render() {
11737
return (
11838
<Switch>
@@ -128,38 +48,38 @@ export class UserRoute extends Fusion<any, any, MyStore> {
12848

12949
Matching `/user/anything/here`
13050
```tsx
131-
<Route match="/user" component={UserRoute}/>
51+
<Route path="/user" component={UserRoute}/>
13252
```
13353

13454
Strict match `/user`
13555
```tsx
136-
<Route match="/user" exact component={UserRoute}/>
56+
<Route path="/user" exact component={UserRoute}/>
13757
```
13858

13959
Render children
14060
```tsx
141-
<Route match="/user">I will be rendered</Route>
61+
<Route path="/user">I will be rendered</Route>
14262
```
14363

14464
Access `route` object via props in your component
14565

14666
```tsx
14767
import * as React from "react";
148-
import { Fusion, Switch, Route } from "fuse-react";
68+
import { Switch, Route } from "fuse-react";
14969

150-
export class UserRoute extends Fusion<any, any> {
70+
export class UserRoute extends React.Component {
15171
init() { }
15272
public render() {
15373
return (
154-
<div>User Id: {this.props.route.params.id}</div>
74+
<div>User Id: {this.props.match.params.id}</div>
15575
)
15676
}
15777
}
15878
```
15979

16080
### Links
16181

162-
The `Link` object is way more flexible comparing to `react-router`'s
82+
The `Link` object is way more flexible comparing to `react-router`'s
16383

16484
Importing
16585
```ts
@@ -181,6 +101,15 @@ Custom render
181101
<div className={active ? 'active' : ''} onClick={navigate}>To user</div>}/>
182102
```
183103

104+
Custom render converts your link into a mini router. You can pass additional property for matching
105+
106+
```tsx
107+
<Link to="/user/add" match="/user" render={(active, navigate) =>
108+
<div className={active ? 'active' : ''} onClick={navigate}>To user</div>}/>
109+
```
110+
111+
In the case above `active` is `true` when navigated to `/user/foobar`, however the `navigate` function navigates to `/user/add`
112+
184113
### Navigation
185114

186115
Access navigation from anywhere in your code!
@@ -224,3 +153,102 @@ Additionally `setQuery` and `mergQuery` accept a second bool argument. Dispatch
224153
mergQuery({foo : "bar"}, false)
225154
// will result in `/user?hello=world&foo=bar`
226155
```
156+
157+
A component can "connect" to an individual key in the store and react to its changes.
158+
159+
160+
The framework also offers a router which has some improvements comparing to `react-router`
161+
162+
```tsx
163+
@connect("count")
164+
class MyUser extends Fusion<any, any, MyStore> {
165+
public render() {
166+
return (
167+
<div>{this.store.count}</div>
168+
);
169+
};
170+
}
171+
```
172+
173+
The decorator `@connect` registers subscription to the store, therefore once we update the object it will be forced to get updated.
174+
175+
```ts
176+
dispatch("count", 1); // like this
177+
dispatch({count : 1}); // or like this
178+
```
179+
180+
## Create your store
181+
182+
```ts
183+
import { createStore } from "fuse-react";
184+
class MyStore {
185+
count = 0;
186+
}
187+
createStore(MyStore);
188+
```
189+
190+
A class will be instantiated and registered globally
191+
192+
## Connecting
193+
194+
A component can be connected to individual keys in the store
195+
```tsx
196+
import { connect } from "fuse-react";
197+
@connect("count", "user")
198+
class MyUser extends Fusion<any, any, MyStore> {
199+
public render() {
200+
return (
201+
<div>{this.store.count}</div>
202+
);
203+
};
204+
}
205+
```
206+
207+
The third (optional) generic typing will help with your typings on `this.store`, meanwhile the first and the second arguments remain conventional(IProps, IState)
208+
209+
### Connecting with deep compare
210+
211+
There are situations where you would like to avoid unnesserary updates. For that preffix your key with `@`
212+
213+
```ts
214+
import { connect } from "fuse-react";
215+
@connect("@user")
216+
class MyUser extends Fusion<any, any, MyStore> {
217+
public render() {
218+
return (
219+
<div>{this.store.user.name}</div>
220+
);
221+
};
222+
}
223+
```
224+
225+
Once the dispatcher recieves an event and goes through all subscriptions it will check if the new value is different from the one in the store.
226+
227+
### Init
228+
229+
```tsx
230+
@connect("count", "user")
231+
class MyUser extends Fusion<any, any, MyStore> {
232+
private init(){}
233+
public render() {
234+
return (
235+
<div>{this.store.count}</div>
236+
);
237+
};
238+
}
239+
```
240+
241+
It's important to understand the `init` of the component, it will be triggered on `componentWillMount` and `componentWillReceiveProps` as well as when a subscription key in the store has been changed.
242+
243+
Avoid dispatching events from `init` as it might cause an infinite loop.
244+
245+
### Dispatch
246+
247+
```tsx
248+
import { dispatch } from "fuse-react";
249+
dispatch("count", 1); // like this
250+
dispatch({count : 1}); // or like this
251+
```
252+
253+
254+

diagram.png

25.9 KB
Loading

src/Router/Route.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ export function setQuery(query ?: {[key:string]: any}, doDispatch : boolean = tr
4040

4141
export class Route extends Fusion<{
4242
children?: any,
43-
match?: string,
44-
path?: string,
43+
path: string,
4544
exact?: boolean
4645
component?: any
4746
}, {}> {

src/Router/Switch.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@ export class Switch extends Fusion<{ children: any }, {}, any> {
1212
if (item.type !== Route) {
1313
throw new Error('Children of Switch must have only Route object')
1414
}
15-
let match = item.props.path || item.props.match;
15+
let match = item.props.path;
1616
if( !item.props.exact){
1717
match += "(.*)";
1818
}
1919
const location = this.store.router.location;
2020
const params = pathMatch(location, match);
2121
if (params) {
2222
if (item.props.component) {
23-
const routeObj = {
23+
const match = {
2424
params: params,
2525
location: location,
26-
match : item.props.match
26+
path : item.props.path
2727
}
2828
const Component = item.props.component;
29-
return <Component key={i} {...{ route: routeObj }} />
29+
return <Component key={i} {...{ match: match }} />
3030
}
3131
return item.props.children;
3232
}

src/dev/UserRoute.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export class UserRoute extends Fusion<any, any, MyStore> {
1414
public render() {
1515
return (
1616
<div>
17-
User with id: {this.props.route.params.id}
17+
User with id: {this.props.match.params.id}
1818
<hr />
1919
<ul>
2020
<li><Link activeClassName="active" to="/user/add">add</Link></li>
@@ -29,10 +29,10 @@ export class UserRoute extends Fusion<any, any, MyStore> {
2929
</ul>
3030

3131
<Switch>
32-
<Route match="/user/add">
32+
<Route path="/user/add">
3333
<h2>Adding new user</h2>
3434
</Route>
35-
<Route match="/user/listing">
35+
<Route path="/user/listing">
3636
<h2>Listing users</h2>
3737
</Route>
3838
</Switch>

src/dev/dev.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ interface IUser {
1818

1919
const wrapper = createStore(MyStore);
2020

21+
//
2122

2223
const q = Query.get("http://google.com/?width=200&height=100")
2324

@@ -44,8 +45,8 @@ class MyRootComponent extends Fusion<any, any, MyStore> {
4445
</ul>
4546
<hr/>
4647
<Switch>
47-
<Route match="/user" component={UserRoute}/>
48-
<Route match="/group">Group route</Route>
48+
<Route path="/user" component={UserRoute}/>
49+
<Route path="/group">Group route</Route>
4950
</Switch>
5051
</div>
5152
</div>

0 commit comments

Comments
 (0)