0.0.2-beta • Published 2 years ago
floorm v0.0.2-beta
floorm
base | orm | door | stone | logger
Declarative state manager for react with orm
Conceived as union of approaches used by such libraries as redux, normalizr, react, effector & mobx
Install
npm i -S floorm
Concept
- ID. Instances of project should have id for access and manipulation
- Pithiness. Every sign of code should have maximum payload with saving readability in project context
- Relations. Immutable updates of instances creates new instances of their parents
- Consistency. Same things should be implemented with same approaches.
- Simple data structures. Data stores in plain objects and simple arrays for comfortable interaction
Guide
- Create orm of your project instances.
// hotel/orm.js
import { orm } from 'floorm'
// book instance have author instance in key "author"
const bookOrm = orm('book', () => ({
author: authorOrm
}))
// author instance have array of book instances in key "books"
const authorOrm = orm('author', () => ({
books: [bookOrm]
}))
- Create doors to orm instances or single-instance stones for use their state through hooks.
// hotel/book.js
import { door, useDoor } from 'floorm'
import { bookOrm } from 'hotel/orm'
const bookDoor = door(bookOrm)
export const useBook = id => {
useEffect(() => {
loadBook(id)
}, [id])
return {
book: useDoor(authorDoor, id),
// with floorm you should not fall into spread-hell with copy all keys like in redux reducers
// put method receives diff like this.setState of react class components with nesting support
// so you can pass object with updated keys of instances only
// missed keys will substituted to next instance from the box
changeName: name => bookDoor.put(id, { name })
}
}
const loadBook = id => bookDoor.put(id, api.book.get(id))
const changeBookName = (id, name) => bookDoor.put(id, { name })
// hotel/author.js
import { door, useDoor } from 'floorm'
import { authorOrm } from 'hotel/orm'
import { api } from 'api'
const authorDoor = useDoor(authorOrm)
export const useAuthor = id => {
useEffect(() => {
loadAuthor(id)
}, [id])
return {
author: useDoor(authorDoor, id),
changeName: name => authorDoor.put(id, { name })
}
}
const loadAuthor = id => authorDoor.put(id, api.authors.get(id))
- Use hooks of your instances in components.
// ui/Book.jsx
import { useBook } from 'hotel/book'
export const Book = ({ id }) => {
const { book, changeName } = useBook(id)
return (
<div>
<input
// every change of book will changed author instance too
// Author component which includes changed author will rerendered for display updated books list
onChange={e => changeName(e.target.value)}
value={book.name}
/>
<div>
author: {author.name}
</div>
</div>
)
}
// ui/Author.jsx
import { useBook } from 'hotel/book'
const Author = ({ id }) => {
const { author, changeName } = useAuthor(id)
return (
<div>
<input
// every change of author will changed his books instances too
// Book components which includes changed author will rerendered for display updated author.name
onChange={e => changeName(e.target.value)}
value={author.name}
/>
{books.map(book => {
<div key={book.id}>{book.name}</div>
})}
</div>
)
}
See demo for more examples.
Or read docs WIP for learn floorm deeply.