react-norm

0.0.0-superbeta-1 • Public • Published

react-norm (beta)

normalized state in hooks

usage

  • describe data relations with orm
  • create stores of related data with store
  • use it state in hooks with useStore
// example
import { orm, store, useStore } from 'react-norm'

const defaultAuthorId = 0

const bookOrm = orm(() => ({
  // by key "author" of any book is some author 
  author: authorOrm
}))

const authorOrm = orm({
  // by key "booksPreview" is array of books
  booksPreview: [bookOrm]
})

const authorBooksOrm = orm(
  [bookOrm]
)

// store for profile
// it fetched once per app when store file is resolved
// and we can pass promise as initial state
// and app will suspended by throw in useStore(profileStore)
const profileStore = store(
  { favoriteAuthors: [authorOrm] },

  api.fetchProfile()
    .catch(e => console.error(e))
)

export const useProfile = () => useStore(profileStore)

const allBooksStore = store(
  [bookOrm],

  api.fetchAllBooks()
)

const authorStore = store(
  authorOrm // orm as 1 arg for orm item usage
  // we can't fetch author at initialization
  // case we need some authorId for it
  // so stores for orms have not initial state
)

const authorBooksStore = store(
  authorBooks
  // it's store of orm authorBooks all items too
)

const useAuthor = authorId => useStore(authorStore, authorId)

const useAuthorBooks = authorId => useStore(authorBooksStore, authorId)

// profile is one for app and we dont need id for access it
// that's why description of profileStore
// ...is just an object but not orm
const useProfile = () => useStore(profileStore)

// books is same story
// it's only one array of books for app
const useBooks = () => useStore(booksStore)

let optimisticAddBookId = 0
const addBook = book => {
  book.id = `optimistic add book id ${optimisticAddBookId++}`
  authorOrm.put(book.author.id, {
    // actualize 3 first books in preview
    booksPreview: current => [book, ...current.slice(2)]
  })
  authorBooksOrm.put(
    book.author.id,
    authorBooks => [book, ...(authorBooks || [])]
  )
  api.addBook(book)
    .then(res =>
      // replace frontend created book to real book from response 
      bookOrm.replace(book.id, res.json)
    )
    .catch(e => {
      bookOrm.remove(book.id)
      console.error('add book error')
    })
}

const removeBook = book => {
  bookOrm.remove(book.id)
  api.removeBook(book.id)
    .catch(() => {
      allBooksStore.put(allBooks => [book, ...(allBooks || [])])
      authorBooksOrm.put(book.author.id, authorBooks => [book, (...authorBooks || [])])
      console.error('remove book error')
    })
}

Package Sidebar

Install

npm i react-norm

Weekly Downloads

2

Version

0.0.0-superbeta-1

License

MIT

Unpacked Size

13.6 kB

Total Files

6

Last publish

Collaborators

  • koevlu