Skip to content

Commit 80ef8a6

Browse files
committed
Update README.md
1 parent ff2173d commit 80ef8a6

File tree

1 file changed

+190
-2
lines changed

1 file changed

+190
-2
lines changed

README.md

Lines changed: 190 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,192 @@
11
redux
2-
=====================
2+
=========================
33

4-
Work in progress
4+
An experiment in fully hot-reloadable Flux.
5+
The API might change any day. Don't use in production.
6+
7+
## What's It Look Like?
8+
9+
### Actions
10+
11+
```js
12+
// Still using constants...
13+
import {
14+
INCREMENT_COUNTER,
15+
DECREMENT_COUNTER
16+
} from '../constants/ActionTypes';
17+
18+
// But action creators are pure functions returning actions
19+
export function increment() {
20+
return {
21+
type: INCREMENT_COUNTER
22+
};
23+
}
24+
25+
export function decrement() {
26+
return {
27+
type: DECREMENT_COUNTER
28+
};
29+
}
30+
31+
// Can also be async if you return a function
32+
// (wow, much functions, so injectable :doge:)
33+
export function incrementAsync() {
34+
return dispatch => {
35+
setTimeout(() => {
36+
dispatch(increment());
37+
}, 1000);
38+
};
39+
}
40+
```
41+
42+
### Stores
43+
```js
44+
// ... too, use constants
45+
import {
46+
INCREMENT_COUNTER,
47+
DECREMENT_COUNTER
48+
} from '../constants/ActionTypes';
49+
50+
// but you can write this part anyhow you like:
51+
52+
const initialState = { counter: 0 };
53+
54+
function incremenent({ counter }) {
55+
return { counter: counter + 1 };
56+
}
57+
58+
function decremenent({ counter }) {
59+
return { counter: counter - 1 };
60+
}
61+
62+
// what's important is that Store is a pure function too
63+
export default function CounterStore(state, action) {
64+
// ... that has an initial state
65+
if (!state) {
66+
return initialState;
67+
}
68+
69+
// and return the new state when an action comes
70+
switch (action.type) {
71+
case INCREMENT_COUNTER:
72+
return incremenent(state, action);
73+
case DECREMENT_COUNTER:
74+
return decremenent(state, action);
75+
default:
76+
return state;
77+
}
78+
}
79+
```
80+
81+
### Components
82+
83+
#### Observing a Single Store
84+
85+
```js
86+
// We're gonna need some decorators
87+
import React from 'react';
88+
import { observes } from 'redux';
89+
90+
// Gonna subscribe it
91+
@observes('CounterStore')
92+
export default class Counter {
93+
render() {
94+
const { counter } = this.props; // injected by @observes
95+
return (
96+
<p>
97+
Clicked: {counter} times
98+
</p>
99+
);
100+
}
101+
}
102+
```
103+
104+
#### Observing Many Stores
105+
106+
```js
107+
// We're gonna need some decorators
108+
import React from 'react';
109+
import { observes } from 'redux';
110+
111+
// With multiple stores, you might want to specify a prop mapper as last argument.
112+
// You can also access `props` inside the prop mapper.
113+
@observes('CounterStore', 'TodoStore', (state, props) => ({
114+
counter: state.CounterStore.counter,
115+
todos: state.TodoStore.todos
116+
}))
117+
export default class TodosWithCounter {
118+
/* ... */
119+
}
120+
```
121+
122+
#### Performing a Single Action
123+
124+
```js
125+
// We're gonna need some decorators
126+
import React from 'react';
127+
import { performs } from 'redux';
128+
129+
// Gonna subscribe it
130+
@performs('increment')
131+
export default class IncrementButton {
132+
render() {
133+
const { increment } = this.props; // injected by @performs
134+
return (
135+
<button onClick={increment}>+</button>
136+
);
137+
}
138+
}
139+
```
140+
141+
#### Performing Many Actions
142+
143+
```js
144+
// We're gonna need some decorators
145+
import React from 'react';
146+
import { performs } from 'redux';
147+
148+
// With multiple actions, you might want to specify a prop mapper as last argument.
149+
// You can also access `props` inside the prop mapper.
150+
@performs('increment', 'decrement', (actions, props) => ({
151+
increment: props.invert ? actions.decrement : actions.increment,
152+
decrement: props.invert ? actions.increment : actions.decrement
153+
}))
154+
export default class IncrementButton {
155+
/* .... */
156+
}
157+
```
158+
159+
### Dispatcher
160+
161+
#### Creating a hot-reloadable dispatcher
162+
163+
```js
164+
import * as stores from './stores/index';
165+
import * as actions from './actions/index';
166+
import { createDispatcher } from 'redux';
167+
168+
const dispatcher =
169+
module.hot && module.hot.data && module.hot.data.dispatcher ||
170+
createDispatcher();
171+
172+
dispatcher.receive(stores, actions);
173+
174+
module.hot.dispose(data => {
175+
data.dispatcher = dispatcher;
176+
});
177+
178+
export default dispatcher;
179+
```
180+
181+
#### Attaching the dispatcher to the root component
182+
183+
```js
184+
import React from 'react';
185+
import { provides } from 'redux';
186+
import dispatcher from './dispatcher';
187+
188+
@provides(dispatcher)
189+
export default class App {
190+
/* ... */
191+
}
192+
```

0 commit comments

Comments
 (0)