Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.1.0 #65

Merged
merged 14 commits into from
Mar 5, 2020
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 = {
};
chenbin92 marked this conversation as resolved.
Show resolved Hide resolved
```

#### 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) {
chenbin92 marked this conversation as resolved.
Show resolved Hide resolved
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 } } `
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useEffectsState 应该是 useModelEffectsState ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createModel 的返回是 useEffectsState
createStore 的返回是 useModelEffectsState


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