Reusable Reducer
As feeble's model allow you create multiple reducers, you can use this feature to write reusable reducers.
Let's say we have a post list and user list on the UI, a post model and a user model keep these lists's state.
// models/post.js
const post = feeble.model({
namespace: 'post',
state: {
loading: false,
data: [],
}
})
post.action('fetch', () => {
method: 'get',
endpoint: '/posts',
})
post.reducer(on => {
on(post.fetch.request, state => ({
...state,
loading: true,
}))
on(post.fetch.success, (state, payload) => ({
...state,
loading: true,
data: payload,
}))
})
// models/user.js
const user = feeble.model({
namespace: 'user',
state: {
loading: false,
data: [],
}
})
user.action('fetch', () => {
method: 'get',
endpoint: '/users',
})
user.reducer(on => {
on(user.fetch.request, state => ({
...state,
loading: true,
}))
on(user.fetch.success, (state, payload) => ({
...state,
loading: true,
data: payload,
}))
})
These two models are 90% similar, especially the reducer. Let's extract the reducer to models/conerns/list.js
:
export default function list(fetch) {
return on => {
on(fetch.request, state => ({
...state,
loading: true,
}))
on(fetch.success, (state, payload) => ({
...state,
loading: true,
data: payload,
}))
}
}
Applying the list
to these models:
// models/post.js
import list from './concerns/list'
const post = feeble.model({
namespace: 'post',
state: {
loading: false,
data: [],
}
})
post.action('fetch', () => {
method: 'get',
endpoint: '/posts',
})
post.reducer(list(fetch))
// models/user.js
import list from './concerns/list'
const user = feeble.model({
namespace: 'user',
state: {
loading: false,
data: [],
}
})
user.action('fetch', () => {
method: 'get',
endpoint: '/users',
})
user.reducer(list(fetch))
// You can create more reducers for other actions
// user.reducer(...)