Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 89 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,34 @@ npm install react-modelx

react-model keep the state and actions in a global store. So you need to register them before using.

`index.ts`

```typescript
import { registerModel } from 'react-modelx'
import Home from '../model/home.model'
import Shared from '../model/shared.model'

registerModel({
Home,
Shared
})
const models = { Home, Shared }

export const {
useStore
}: { useStore: UseStore<keyof typeof models, typeof models> } = registerModel(
models
)
```

`index.js`

```javascript
import { registerModel } from 'react-modelx'
import Home from '../model/home.model'
import Shared from '../model/shared.model'

const models = { Home, Shared }

export const {
useStore
}
```

### useStore
Expand All @@ -44,7 +63,7 @@ The functional component in React 16.7 can use Hooks to connect the global store

```javascript
import React from 'react'
import { useStore } from 'react-modelx'
import { useStore } from './index'

export default () => {
const [state, actions] = useStore('Home')
Expand All @@ -65,6 +84,69 @@ export default () => {
}
```

### Model

Every model have their own state and actions.

```typescript
const initialState = {
counter: 0,
light: false,
response: {} as {
code: number
message: string
}
}

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

const Model = {
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
} as ModelType<StateType, ActionsParamType> // The Modal actions type will generate automatically by the StateType and ActionParamsType

export default Model

type ConsumerActionsType = getConsumerActionsType<typeof Model.actions>
type ConsumerType = { actions: ConsumerActionsType; state: StateType }
type ActionType = ConsumerActionsType

export { ConsumerType, StateType, ActionType }
```

### getState

Key Point: [State variable not updating in useEffect callback](https://github.com/facebook/react/issues/14066)
Expand Down Expand Up @@ -92,6 +174,8 @@ const BasicHook = () => {
}
```

## Other Concept required by Class Component

### Provider

The global state standalone can not effect the react class components, we need to provide the state to react root component.
Expand Down Expand Up @@ -182,66 +266,3 @@ export default connect(
mapProps
)(TSCounter)
```

### Model

Every model have their own state and actions.

```typescript
const initialState = {
counter: 0,
light: false,
response: {} as {
code: number
message: string
}
}

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

const Model = {
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
} as ModelType<StateType, ActionsParamType> // The Modal actions type will generate automatically by the StateType and ActionParamsType

export default Model

type ConsumerActionsType = getConsumerActionsType<typeof Model.actions>
type ConsumerType = { actions: ConsumerActionsType; state: StateType }
type ActionType = ConsumerActionsType

export { ConsumerType, StateType, ActionType }
```