Skip to content

Commit

Permalink
Merge branch 'master' into v2
Browse files Browse the repository at this point in the history
  • Loading branch information
ArrayZoneYour authored May 15, 2019
2 parents 0ea86fd + dc3625b commit 17c609a
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 206 deletions.
80 changes: 7 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ const Todo = {
// s is the readonly version of state
// you can also return partial state here but don't need to keep immutable manually
// state is the mutable state
return state => state.items.push(todo)
return state => {
state.items.push(todo)
}
}
}
}
Expand Down Expand Up @@ -56,6 +58,8 @@ const TodoList = () => {

[Next.js + react-model work around](https://github.com/byte-fe/react-model-experiment)

[v2 docs](https://github.com/byte-fe/react-model/blob/v2/README.md)

install package

```shell
Expand Down Expand Up @@ -83,85 +87,15 @@ npm install react-model
- [How can I add custom middleware](#how-can-i-add-custom-middleware)
- [How can I make persist models](#how-can-i-make-persist-models)
- [How can I deal with local state](#how-can-i-deal-with-local-state)
- [actions throw error from immer.module.js](#actions-throw-error-from-immer.module.js)
- [How can I customize each model's middlewares?](#how-can-i-customize-each-model's-middlewares)
- [actions throw error from immer.module.js](#actions-throw-error-from-immermodulejs)
- [How can I customize each model's middlewares?](#how-can-i-customize-each-models-middlewares)

## Core Concept

### Model

Every model have their own state and actions.

<details>
<summary><del>old model</del> (will be deprecated in v3.0)</summary>
<p>

```typescript
const initialState = {
counter: 0,
light: false,
response: {}
}

interface StateType = {
counter: number
light: boolean
response: {
code?: number
message?: string
}
}

interface ActionsParamType = {
increment: number
openLight: undefined
get: undefined
} // You only need to tag the type of params here !

const model: ModelType<StateType, ActionsParamType> = {
actions: {
increment: async (state, _, params) => {
return {
counter: state.counter + (params || 1)
}
},
openLight: async (state, actions) => {
await actions.increment(1) // You can use other actions within the model
await actions.get() // support async functions (block actions)
actions.get()
await actions.increment(1) // + 1
await actions.increment(1) // + 2
await actions.increment(1) // + 3 as expected !
return { light: !state.light }
},
get: async () => {
await new Promise((resolve, reject) =>
setTimeout(() => {
resolve()
}, 3000)
)
return {
response: {
code: 200,
message: `${new Date().toLocaleString()} open light success`
}
}
}
},
state: initialState
}

export default model

// You can use these types when use Class Components.
// type ConsumerActionsType = getConsumerActionsType<typeof Model.actions>
// type ConsumerType = { actions: ConsumerActionsType; state: StateType }
// type ActionType = ConsumerActionsType
// export { ConsumerType, StateType, ActionType }
```
</p>
</details>

```typescript
const initialState = {
counter: 0,
Expand Down
19 changes: 19 additions & 0 deletions __test__/actions/unmount.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/// <reference path="../index.d.ts" />
import 'react-testing-library/cleanup-after-each'
import { testHook } from 'react-hooks-testing-library'
import { ActionsTester } from '../index'
import { Model } from '../../src'

describe('actions', () => {
test('call actions in action', async () => {
const { useStore } = Model({ ActionsTester })
let state: any
let actions: any
const { unmount } = testHook(() => {
;[state, actions] = useStore('ActionsTester')
})
await actions.getData()
unmount()
expect(state.data).toEqual({ counter: 1000 })
})
})
96 changes: 48 additions & 48 deletions __test__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@ import { timeout } from '../src/helper'
import { actionMiddlewares } from '../src/middlewares'

export const ActionsTester: ModelType<ActionTesterState, ActionTesterParams> = {
state: {
response: {
data: {}
},
data: {}
},
actions: {
get: async () => {
const response = await timeout(9, { code: 0, data: { counter: 1000 } })
return { response }
},
getData: async (_, { actions }) => {
await actions.get()
actions.parse()
},
parse: () => {
return state => {
state.data = state.response.data
}
},
getData: async (_, actions) => {
await actions.get()
actions.parse()
}
},
state: {
data: {},
response: {
data: {}
}
}
}
Expand All @@ -32,113 +32,113 @@ export const Counter: ModelType<
CounterState,
CounterActionParams & ExtraActionParams
> = {
state: { count: 0 },
actions: {
increment: (_, __, params) => {
return state => {
state.count += params
}
},
add: (state, __, params) => {
add: (params, { state }) => {
return {
count: state.count + params
}
},
addCaller: (_, actions) => {
actions.add(5)
},
increment: params => {
return state => {
state.count += params
}
}
}
},
state: { count: 0 }
}

// v3.0
export const NextCounter: NextModelType<
export const NextCounter: ModelType<
CounterState,
CounterActionParams & ExtraActionParams
> = {
state: { count: 0 },
actions: {
increment: params => {
return state => {
state.count += params
}
},
add: (params, { state }) => {
return {
count: state.count + params
}
},
addCaller: (_, { actions }) => {
actions.add(5)
},
increment: params => {
return state => {
state.count += params
}
}
}
},
state: { count: 0 }
}

export const Theme: ModelType<ThemeState, ThemeActionParams> = {
state: {
theme: 'dark'
},
actions: {
changeTheme: state => ({
changeTheme: (_, { state }) => ({
theme: state.theme === 'dark' ? 'light' : 'dark'
})
},
state: {
theme: 'dark'
}
}

export const AsyncCounter: ModelType<CounterState, CounterActionParams> = {
state: { count: 0 },
asyncState: async (context: { count?: number }) => ({
count: context ? context.count || 1 : 1
}),
actions: {
increment: (_, __, params) => {
increment: params => {
return state => {
state.count += params
}
}
}
},
asyncState: async (context: { count?: number }) => ({
count: context ? context.count || 1 : 1
}),
state: { count: 0 }
}

export const AsyncNull: ModelType<CounterState, CounterActionParams> = {
state: { count: 0 },
actions: {
increment: (_, __, params) => {
increment: params => {
return state => {
state.count += params
}
}
}
},
state: { count: 0 }
}

export const TimeoutCounter: ModelType<CounterState, CounterActionParams> = {
state: { count: 0 },
asyncState: async () => ({
count: 1
}),
actions: {
increment: async (_, __, params) => {
increment: async (params, { state: _ }) => {
await timeout(4000, {})
return (state: typeof _) => {
state.count += params
}
}
}
},
asyncState: async () => ({
count: 1
}),
state: { count: 0 }
}

export const ErrorCounter: ModelType<CounterState, CounterActionParams> = {
state: { count: 0 },
actions: {
increment: async () => {
throw 'error'
}
}
},
state: { count: 0 }
}

const delayMiddleware: Middleware = async (context, restMiddlewares) => {
await timeout(2000, {})
context.next(restMiddlewares)
}

const nextCounterModel: NextModelType<CounterState, NextCounterActionParams> = {
const nextCounterModel: ModelType<CounterState, NextCounterActionParams> = {
actions: {
add: num => {
return state => {
Expand Down
13 changes: 8 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-model",
"version": "2.7.1",
"version": "3.0.0-alpha.1",
"description": "The State management library for React",
"main": "./dist/react-model.js",
"umd:main": "./dist/react-model.umd.js",
Expand All @@ -17,7 +17,7 @@
"author": "ArrayZoneYour <[email protected]>",
"license": "MIT",
"dependencies": {
"immer": "^2.0.0"
"immer": "^3.0.0"
},
"peerDependencies": {
"react": "^16.3.0",
Expand All @@ -26,8 +26,10 @@
"devDependencies": {
"@commitlint/cli": "^7.5.2",
"@commitlint/config-conventional": "^7.5.0",
"@types/babel__core": "^7.1.1",
"@types/babel__template": "^7.0.2",
"@types/jest": "^24.0.5",
"@types/node": "^11.9.4",
"@types/node": "^12.0.0",
"@types/react": "^16.8.2",
"@types/react-dom": "^16.8.0",
"commitizen": "^3.0.7",
Expand All @@ -37,8 +39,9 @@
"prettier": "^1.16.4",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"react-hooks-testing-library": "^0.4.0",
"react-testing-library": "^6.0.0",
"react-hooks-testing-library": "^0.5.0",
"react-test-renderer": "^16.8.6",
"react-testing-library": "^7.0.0",
"remark-cli": "^6.0.1",
"remark-lint": "^6.0.4",
"remark-preset-lint-recommended": "^3.0.2",
Expand Down
Loading

0 comments on commit 17c609a

Please sign in to comment.