Skip to content

Commit b5e82af

Browse files
authored
Merge pull request #92 from byte-fe/feat/Model
feat(model): refactor model initialize method
2 parents 2e51b26 + 12fce12 commit b5e82af

File tree

15 files changed

+400
-142
lines changed

15 files changed

+400
-142
lines changed

.npmignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ coverage/
2929
.rts2_cache_umd/
3030

3131
# Github
32-
.github/
32+
.github/
33+
.git/

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ npm install react-model
8181
- [FAQ](#faq)
8282
- [How can I disable the console debugger?](#how-can-i-disable-the-console-debugger)
8383
- [How can I add custom middleware](#how-can-i-add-custom-middleware)
84+
- [How can I make persist models](#how-can-i-make-persist-models)
8485

8586
## Core Concept
8687

@@ -655,3 +656,21 @@ export default Model(stores)
655656
```
656657
657658
[⇧ back to top](#table-of-contents)
659+
660+
#### How can I make persist models
661+
662+
```typescript
663+
import { actionMiddlewares, Model } from 'react-model'
664+
import Example from 'models/example'
665+
666+
const persistMiddleware: Middleware = async (context, restMiddlewares) => {
667+
localStorage.setItem('__REACT_MODEL__', JSON.stringify(context.Global.State))
668+
await context.next(restMiddlewares)
669+
}
670+
671+
actionMiddlewares.push(persistMiddleware)
672+
673+
Model({ Example }, JSON.parse(localStorage.getItem('__REACT_MODEL__')))
674+
```
675+
676+
[⇧ back to top](#table-of-contents)

__test__/Model/mixed.spec.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/// <reference path="../index.d.ts" />
2+
import { testHook } from 'react-hooks-testing-library'
3+
import { NextCounter } from '..'
4+
import { Model } from '../../src'
5+
6+
describe('useStore', () => {
7+
test('create by single model definition', async () => {
8+
let state: any
9+
let actions: any
10+
let count = 0
11+
const Home = Model(NextCounter)
12+
const { useStore, subscribe, unsubscribe } = Model({ Home })
13+
testHook(() => {
14+
;[state, actions] = useStore('Home')
15+
})
16+
expect(state).toEqual({ count: 0 })
17+
await actions.increment(3)
18+
expect(state).toEqual({ count: 3 })
19+
// test subscribe
20+
subscribe('Home', 'increment', () => (count += 1))
21+
await actions.increment(4)
22+
expect(count).toBe(1)
23+
expect(state.count).toBe(7)
24+
// test unsubscribe
25+
unsubscribe('Home', 'increment')
26+
await actions.increment(3)
27+
expect(state.count).toBe(10)
28+
expect(count).toBe(1)
29+
})
30+
})

__test__/Model/single.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/// <reference path="../index.d.ts" />
2+
import { testHook } from 'react-hooks-testing-library'
3+
import { NextCounter } from '..'
4+
import { Model } from '../../src'
5+
6+
describe('useStore', () => {
7+
test('create by single model definition', async () => {
8+
let state: any
9+
let actions: any
10+
let count = 0
11+
const { useStore, subscribe, unsubscribe } = Model(NextCounter)
12+
testHook(() => {
13+
;[state, actions] = useStore()
14+
})
15+
expect(state).toEqual({ count: 0 })
16+
await actions.increment(3)
17+
expect(state).toEqual({ count: 3 })
18+
// test subscribe
19+
subscribe('increment', () => (count += 1))
20+
await actions.increment(4)
21+
expect(count).toBe(1)
22+
expect(state.count).toBe(7)
23+
// test unsubscribe
24+
unsubscribe('increment')
25+
await actions.increment(3)
26+
expect(state.count).toBe(10)
27+
expect(count).toBe(1)
28+
})
29+
})

__test__/class/class.spec.tsx

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import * as React from 'react'
44
import { Model, Provider, connect } from '../../src'
55
import { Counter } from '../index'
66
import { render, fireEvent } from 'react-testing-library'
7-
import { testHook } from 'react-hooks-testing-library'
87
import { timeout } from '../../src/helper'
98

109
const Button = connect(
@@ -51,22 +50,4 @@ describe('class component', () => {
5150
await timeout(100, {}) // Wait Consumer rerender
5251
expect(button!.textContent).toBe('3')
5352
})
54-
test('communicator', async () => {
55-
let state: any
56-
const { useStore } = Model({ Counter })
57-
testHook(() => {
58-
;[state] = useStore('Counter')
59-
})
60-
const { container } = render(
61-
<Provider>
62-
<Button />
63-
</Provider>
64-
)
65-
const button: any = container.firstChild
66-
expect(button!.textContent).toBe('0')
67-
fireEvent.click(button)
68-
await timeout(100, {}) // Wait Consumer rerender
69-
expect(button!.textContent).toBe('3')
70-
expect(state.count).toBe(3)
71-
})
7253
})
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/// <reference path="../index.d.ts" />
2+
import 'react-testing-library/cleanup-after-each'
3+
import * as React from 'react'
4+
import { Model, Provider, connect } from '../../src'
5+
import { Counter } from '../index'
6+
import { render, fireEvent } from 'react-testing-library'
7+
import { testHook } from 'react-hooks-testing-library'
8+
import { timeout } from '../../src/helper'
9+
10+
const Button = connect(
11+
'Counter',
12+
(props: any) => props
13+
)(
14+
class extends React.PureComponent<any> {
15+
render() {
16+
const { state, actions } = this.props
17+
return (
18+
<button
19+
onClick={() => {
20+
actions.increment(3).catch((e: any) => console.error(e))
21+
}}
22+
>
23+
{state.count}
24+
</button>
25+
)
26+
}
27+
}
28+
)
29+
30+
describe('class component', () => {
31+
test('communicator', async () => {
32+
let state: any
33+
const { useStore } = Model({ Counter })
34+
testHook(() => {
35+
;[state] = useStore('Counter')
36+
})
37+
const { container } = render(
38+
<Provider>
39+
<Button />
40+
</Provider>
41+
)
42+
const button: any = container.firstChild
43+
expect(button!.textContent).toBe('0')
44+
fireEvent.click(button)
45+
await timeout(100, {}) // Wait Consumer rerender
46+
expect(button!.textContent).toBe('3')
47+
expect(state.count).toBe(3)
48+
})
49+
})

__test__/getActions.spec.ts

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/// <reference path="./index.d.ts" />
22
import { testHook } from 'react-hooks-testing-library'
3+
import { Counter } from '.'
34
import { Model } from '../src'
4-
import { Counter, AsyncCounter } from '.'
55

66
describe('useStore', () => {
77
test('return default initial values', () => {
@@ -25,22 +25,4 @@ describe('useStore', () => {
2525
await actions.increment(4)
2626
expect(state.count).toBe(7)
2727
})
28-
test('consumer actions return Partial<State>', async () => {
29-
let state: any
30-
let actions: any
31-
const { useStore, getActions } = Model({ Counter })
32-
testHook(() => {
33-
;[state] = useStore('Counter')
34-
actions = getActions('Counter')
35-
})
36-
await actions.add(3)
37-
expect(state).toEqual({ count: 3 })
38-
})
39-
test('use initialModels', async () => {
40-
const { getInitialState } = Model({ AsyncCounter })
41-
const initialModels = await getInitialState()
42-
const { getState } = Model({ AsyncCounter }, initialModels)
43-
const state = getState('AsyncCounter')
44-
expect(state.count).toBe(1)
45-
})
4628
})

__test__/index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,26 @@ export const Counter: ModelType<
4545
}
4646
}
4747

48+
// v3.0
49+
export const NextCounter: NextModelType<
50+
CounterState,
51+
CounterActionParams & ExtraActionParams
52+
> = {
53+
state: { count: 0 },
54+
actions: {
55+
increment: params => {
56+
return state => {
57+
state.count += params
58+
}
59+
},
60+
add: (params, { state }) => {
61+
return {
62+
count: state.count + params
63+
}
64+
}
65+
}
66+
}
67+
4868
export const Theme: ModelType<ThemeState, ThemeActionParams> = {
4969
state: {
5070
theme: 'dark'

__test__/useStore.spec.ts

Lines changed: 0 additions & 44 deletions
This file was deleted.

__test__/useStore/actions.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/// <reference path="../index.d.ts" />
2+
import { testHook } from 'react-hooks-testing-library'
3+
import { Counter } from '..'
4+
import { Model } from '../../src'
5+
6+
describe('useStore', () => {
7+
test('consumer actions return Partial<State>', async () => {
8+
let state: any
9+
let actions: any
10+
const { useStore } = Model({ Counter })
11+
testHook(() => {
12+
;[state, actions] = useStore('Counter')
13+
})
14+
await actions.add(3)
15+
expect(state).toEqual({ count: 3 })
16+
})
17+
})

0 commit comments

Comments
 (0)