Skip to content

Commit

Permalink
Merge pull request #65 from ice-lab/release/1.1.0
Browse files Browse the repository at this point in the history
Release 1.1.0
  • Loading branch information
chenbin92 authored Mar 5, 2020
2 parents 95a6114 + c7870a4 commit cc5c015
Show file tree
Hide file tree
Showing 13 changed files with 442 additions and 208 deletions.
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,16 @@ const delay = (time) => new Promise((resolve) => setTimeout(() => resolve(), tim
// 1️⃣ Use a model to define your store
const counter = {
state: 0,
actions: {
reducers: {
increment:(prevState) => prevState + 1,
async decrement(prevState) {
decrement:(prevState) => prevState - 1,
},
effects: {
async decrementAsync(state, payload, actions) {
await delay(1000);
return prevState - 1;
actions.decrement();
},
},
}
};

const models = {
Expand All @@ -66,12 +69,12 @@ const store = createStore(models);
const { useModel } = store;
function Counter() {
const [ count, actions ] = useModel('counter');
const { increment, decrement } = actions;
const { increment, decrementAsync } = actions;
return (
<div>
<span>{count}</span>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<button type="button" onClick={increment}>+</button>
<button type="button" onClick={decrementAsync}>-</button>
</div>
);
}
Expand Down
95 changes: 51 additions & 44 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ const {
Provider,
useModel,
useModelActions,
useModelActionsState,
useModelEffectsState,
withModel,
withModelActions,
withModelActionsState,
withModelEffectsState,
} = createStore(models);
```

Expand Down Expand Up @@ -55,31 +55,44 @@ const model = {
};
```

#### actions
#### reducers

`actions: { [string]: (prevState, payload, actions, globalActions) => any }`
`reducers: { [string]: (prevState, payload) => any }`

An object of functions that change the model's state. These functions take the model's previous state and a payload, and return the model's next state.
An object of functions that change the model's state. These functions take the model's previous state and a payload, and return the model's next state. These should be pure functions relying only on the state and payload args to compute the next state. For code that relies on the "outside world" (impure functions like api calls, etc.), use effects.

```js
const counter = {
state: 0,
actions: {
add: (prevState, payload) => prevState + payload,
},
reducers: {
add: (state, payload) => state + payload,
}
};
```

Actions provide a simple way of handling async actions when used with async/await:
#### effects

`effects: { [string]: (prevState, payload, actions, globalActions) => void }`

An object of functions that can handle the world outside of the model. Effects provide a simple way of handling async actions when used with async/await.

```js
const counter = {
actions: {
async addAsync(prevState, payload) => {
await delay(1000);
return prevState + payload;
state: 0,
effects: {
async add(prevState, payload, actions) {
// wait for data to load
const response = await fetch('http://example.com/data');
const data = await response.json();
// pass the result to a local reducer
actions.update(data);
},
},
reducers: {
update(prev, data) {
return {...prev, ...data};
}
},
};
```

Expand All @@ -90,25 +103,19 @@ const user = {
state: {
foo: [],
},
actions: {
effects: {
like(prevState, payload, actions, globalActions) => {
actions.foo(payload); // call user's actions
globalActions.user.foo(payload); // call actions of another model

// do something...

return {
...prevState,
};
},
foo(prevState, id) {
// do something...

},
reducres: {
foo(prevState, payload) {
return {
...prevState,
};
},
},
}
};
```

Expand Down Expand Up @@ -179,15 +186,15 @@ const counter = {
state: {
value: 0,
},
actions: {
reducers: {
add: (prevState, payload) => ({...prevState, value: prevState.value + payload}),
},
};

const { userModel } = createStore({ counter });
const { useModel } = createStore({ counter });

function FunctionComponent() {
const [ state, actions ] = userModel('name');
const [ state, actions ] = useModel('counter');

state.value; // 0

Expand All @@ -203,28 +210,28 @@ A hook granting your components access to the model actions.

```js
function FunctionComponent() {
const actions = useModelActions('name');
const actions = useModelActions('counter');
actions.add(1);
}
```

### useModelActionsState
### useModelEffectsState

`useModelActionsState(name: string): { [actionName: string]: { isLoading: boolean, error: Error } } `
`useModelEffectsState(name: string): { [actionName: string]: { isLoading: boolean, error: Error } } `

A hook granting your components access to the action state of the model.

```js
function FunctionComponent() {
const actions = useModelActions('foo');
const actionsState = useModelActionsState('foo');
const actions = useModelActions('counter');
const effectsState = useModelEffectsState('counter');

useEffect(() => {
actions.fetch();
}, []);

actionsState.fetch.isLoading;
actionsState.fetch.error;
effectsState.fetch.isLoading;
effectsState.fetch.error;
}
```

Expand Down Expand Up @@ -319,16 +326,16 @@ export default withModelActions('todos')(TodoList);

You can use `mapModelActionsToProps` to set the property as the same way like `mapModelToProps`.

### withModelActionsState
### withModelEffectsState

`withModelActionsState(name: string, mapModelActionsStateToProps?: (actionsState) => Object = (actionsState) => ({ [name]: actionsState }) ): (React.Component) => React.Component`
`withModelEffectsState(name: string, mapModelActionsStateToProps?: (effectsState) => Object = (effectsState) => ({ [name]: effectsState }) ): (React.Component) => React.Component`

```tsx
import { ModelActionsState, ModelActions } from '@ice/store';
import todosModel from '@/models/todos';
import store from '@/store';

const { withModelActionsState } = store;
const { withModelEffectsState } = store;

interface Props {
todosActionsState: ModelActionsState<typeof todosModel>; // `todosActionsState` automatically adds `${modelName}ActionsState` as the property
Expand All @@ -342,7 +349,7 @@ class TodoList extends Component<Props> {
}
}

export default withModelActionsState('todos')(TodoList);
export default withModelEffectsState('todos')(TodoList);
```

You can use `mapModelActionsStateToProps` to set the property as the same way like `mapModelToProps`.
Expand All @@ -361,7 +368,7 @@ const [
Provider,
useState,
useActions,
useActionsState,
useEffectsState,
] = createModel(model);
```

Expand Down Expand Up @@ -439,22 +446,22 @@ function FunctionComponent() {
}
```

### useActionsState
### useEffectsState

`useActionsState(): { [actionName: string]: { isLoading: boolean, error: Error } } `
`useEffectsState(): { [actionName: string]: { isLoading: boolean, error: Error } } `

A hook granting your components access to the action state of the model.

```js
function FunctionComponent() {
const actions = useActions();
const actionsState = useActionsState();
const effectsState = useEffectsState();

useEffect(() => {
actions.fetch();
}, []);

actionsState.fetch.isLoading;
actionsState.fetch.error;
effectsState.fetch.isLoading;
effectsState.fetch.error;
}
```
Loading

0 comments on commit cc5c015

Please sign in to comment.