reedx
Version:
Like redux but with less code
204 lines (149 loc) • 4.61 kB
Markdown
# Reedx
## Vantagens
- Like redux, porém com menos boilerplate e teorias.
- Sem necessidade de instalar vários packages.
- Sem reducers, actions, types, whatevers.
- Integra normalmente com as libs do Redux (middlewares, devtools, etc).
## Arquitetura
<p align="center"><img src="https://d26dzxoao6i3hh.cloudfront.net/items/132N310h2i3r3J2Y1d3a/reedx%20.png?v=a782bd63" height=700" /></p>
### Model
Um `model` é responsável por guardar dados e expor métodos. Não é possível modificar um model senão for atráves de um método (`reducer`) responsável por isso.
### Reducers
São os métodos responsáveis por modificar as propriedades base de um `model`. Um `reducer` pode modificar apenas o seu próprio `model`.
### Computed
Colocar muita lógica referente ao seu model nos reducers não é a melhor maneira de tornar seu código readable. Para isso existe as `computed properties`, que são propriedades não armazenadas na memória do seu model, mas que serão expostas ao conectar o mesmo em algum componente. Este conceito é algo muito parecido do que é possível com os seletores no Redux.
## Types
- `Model: { [key:string]: any }`
- `Action: Object<type: string, payload: any, error: boolean>`
- `Reducer: { [key: string]: (state: Model, action: Action) => void }`
- `Computed: { [key: string]: (state: Model, props: Object) => any }`
## API
### `model({ name, state, computed, reducers })`
#### params
- `name: string`
- `state: State`
- `computed: Object<Computed>`
- `reducers: Object<Reducers>`
#### exemplos
```js
import { model } from 'reedx'
const state = {
entities: [],
selectedId: ''
}
const reducers = {
addUser(state, { payload: user }) {
return Object.assign({}, state, { entities: [...state.entities, user] }),
},
selectUser(state, { payload: id }) {
return Object.assign({}, state, { selectedId: id })
}
}
export default model({ name: 'users', state, reducers })
```
ou usando as `computed properties`:
```js
import { model } from 'reedx'
const state = {
entities: [],
selectedId: ''
}
const computed = {
user(state) {
const { users } = state
return users.entities.find(user => user.id === users.selectedId)
}
}
const reducers = {
addUser(state, { payload: user }) {
return Object.assign({}, state, { entities: [...state.entities, user] }),
},
selectUser(state, { payload: id }) {
return Object.assign({}, state, { selectedId: id })
}
}
export default model({ name: 'users', state, computed, reducers })
```
### `propsFrom(...models)`
#### params
- `models: Model`
#### exemplos
```js
import React from 'react'
import { connect } from 'react-redux'
import { propsFrom } from 'reedx'
import { users } from './models'
const Users = ({ users, selectedId }) => (
/* */
)
export default connect(propsFrom(users))(Users)
```
### `handlersFrom(...models)`
#### params
- `models: Model`
#### exemplo
```js
import React from 'react'
import { connect } from 'react-redux'
import { propsFrom, handlersFrom } from 'reedx'
import { users } from './models'
const Users = ({ users, selectedId, selectUser }) => (
/* */
)
export default connect(propsFrom(users), handlersFrom(users))
```
### `pick(model, properties)`
#### params
- `model: Model`
- `properties: Array<string>`
#### exemplo
```js
import { model, propsFrom, pick } from 'reedx'
const users = model({
name: 'users',
state: {
all: [],
selectedId: null,
}
})
const mapProps = propsFrom(
pick(users, ['selectedId']))
)
console.log(mapProps({ users })) // { selectedId }
```
### `omit(model, properties)`
#### params
- `model: Model`
- `properties: Array<string>`
#### exemplo
```js
import { model, propsFrom, omit } from 'reedx'
const users = model({
name: 'users',
state: {
all: [],
selectedId: null,
}
})
const mapProps = propsFrom(
omit(users, ['selectedId']))
)
console.log(mapProps({ users })) // { all }
```
## Renomeando propriedades ao conectar
Algumas vezes você pode ter proprieades com o mesmo valor entre models diferentes e ter a necessidade de conectar os dois na mesma view. Neste cenário, você teria a última propriedade sobrescrevendo a primeira devido aos seus valores serem iguais. Para evitar isso, basta você setar o novo nome da sua variável usando `:` após a definição no método de `pick` ou `omit`
```js
import { model, propsFrom, pick } from 'reedx'
const users = model({
name: 'users',
state: {
otherProp: null,
}
})
const mapProps = propsFrom(
pick(users, ['otherProp:prop'])
)
console.log(mapProps({ users })) // { prop }
```