1.1.1 • Published 10 months ago

use-mobx-observable v1.1.1

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

use-mobx-observable

npm version pages-build-deployment npm Coverage Status

Use mobx observable like useState

Note:

Install

npm install mobx@^6 react@^16.8 # peer dependencies
npm install use-mobx-observable

šŸ‘‰API DocsšŸ‘ˆ

Problem

The current mobx hooks from mobx-react-lite uses pattern like below:

function MyComponent() {

  let store = useLocalObservable(() => ({ count: 0 }))

  return (
    <Observer>                      // <---
    {                               // <---
      () =>                         // <---
        <div>{store.count}</div>
    }                               // <---
    </Observer>                     // <---
  )
}

To be reactive, you have to wrap your jsx with <Observer> and use render props, which is not a favorable way.

There was a Discussion around this issue. At the end of it, simple solution was proposed:

function useSelector(select) {
  const [selected, setSelected] = useState(select)
  useEffect(() => autorun(() => setSelected(select())), [])
  return selected
}

function myComponent({ observableOrder }) {
  const latestPrice = useSelector(() => observableOrder.price)
  return <h1>{latestPrice}</h1>
}

However, in practice, you'll still need to create an observable for computed and actions.

Do it at once

import { useObservable, select, useMultiObservables } from 'use-mobx-observable'

function MyComponent() {

  // create local observable, with plain object or an initializer
  let store = useObservable({
      count: 0,
      get countText() {
        return `Count: ${this.count}`
      },
      add() {
        this.count += 1
      },
    })

  // map external observable props to getters
  let store2 = useObservable(select(externalStore, ['propsA', 'propsB'])({ count: 0 }/* Optional */))

  // chaining with lodash.flow for mapping multiple sources
  let store3 = useObservable(
    _.flow(
      select(externalStore, ['propsA', 'propsB'],
      select(externalStore2, { renameC: 'propsC' },  // rename getters
    )({
      get sum() {
        return this.propsA + this.renameC
      }
     })
  )

  // use observable directly, returned value can be omitted since it is the same as input
  // Be ware of the performance impact: any props change will trigger a rerender.
  useObservable(store)

  return (
    <div>
      <h1>{store.countText}</h1>
      <button onClick={() => store.add()}>Add</button>
    </div>
  )
}
1.1.1

10 months ago

1.0.2

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.1.0-alpha.1

2 years ago

1.1.0-beta.1

2 years ago

1.1.0-alpha.2

2 years ago

1.1.0-beta.0

2 years ago

1.1.0-alpha.0

2 years ago

1.1.0-alpha.3

2 years ago

1.1.0-alpha.4

2 years ago

1.0.1

3 years ago

1.0.0

3 years ago

0.1.10

3 years ago

0.1.8

3 years ago

0.1.9

3 years ago

0.1.2

4 years ago

0.1.7

4 years ago

0.1.4

4 years ago

0.1.3

4 years ago

0.1.6

4 years ago

0.1.5

4 years ago

0.0.10

4 years ago

0.0.11

4 years ago

0.1.0

4 years ago

0.1.1

4 years ago

0.0.9

4 years ago

0.0.8

4 years ago

0.0.7-alpha.1

4 years ago

0.0.7-alpha.0

4 years ago

0.0.7-0

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago