Sentre
Search…
Model & Controllers
Cook and manage DApp's states by Redux Toolkit.

Single model - Multiple controllers

Model

Typically, the model always has a single file that is to merge all the controllers' states into the store.
1
// model/index.ts
2
​
3
import { configureStore } from '@reduxjs/toolkit'
4
import { devTools, bigintSerializationMiddleware } from 'shared/devTools'
5
​
6
import main from 'app/model/main.controller'
7
​
8
/**
9
* Isolated store
10
*/
11
const model = configureStore({
12
middleware: (getDefaultMiddleware) =>
13
getDefaultMiddleware(bigintSerializationMiddleware),
14
devTools: devTools(process.env.REACT_APP_ID as string),
15
reducer: {
16
main,
17
},
18
})
19
​
20
export type AppState = ReturnType<typeof model.getState>
21
export type AppDispatch = typeof model.dispatch
22
export default model
Copied!
Following the template, your DApp's state is isolated in a store named myapp. If you installed Redux Devtool, you are able to inspect the myapp states clearly.
The isolated states of myapp.
Additionally, the model will merge all states in reducer (i.e. main is the current state declared in the reducer) which are exported from controllers. To import a new state, you merely need to add the state into the reducer.

Controllers

Controllers typically are to fetch raw data, process it to good forms, and export it to the model.
1
// main.controller.ts
2
​
3
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
4
​
5
/**
6
* Interface & Utility
7
*/
8
​
9
export type State = {
10
counter: number
11
}
12
​
13
/**
14
* Store constructor
15
*/
16
​
17
const NAME = 'main'
18
const initialState: State = {
19
counter: 0,
20
}
21
​
22
/**
23
* Actions
24
*/
25
​
26
export const increaseCounter = createAsyncThunk<State, void, { state: any }>(
27
`${NAME}/increaseCounter`,
28
async (_, { getState }) => {
29
const {
30
main: { counter },
31
} = getState()
32
return { counter: counter + 1 }
33
},
34
)
35
​
36
/**
37
* Usual procedure
38
*/
39
​
40
const slice = createSlice({
41
name: NAME,
42
initialState,
43
reducers: {},
44
extraReducers: (builder) =>
45
void builder.addCase(
46
increaseCounter.fulfilled,
47
(state, { payload }) => void Object.assign(state, payload),
48
),
49
})
50
​
51
export default slice.reducer
Copied!
By the example, the name and struct of the state had been assigned at lines 15, 16. The function increaseCounter is to compute and return the next state partially which will mutate the current state in slice (i.e. line 38 to build a state and line 44 to catch the next state from increaseCounter).
Examine Best Practices for more examples.
Last modified 5mo ago
Copy link