mobxjs / mobx-react

React bindings for MobX

Home Page:https://mobx.js.org/react-integration.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Conditional useObserver hook

AjaxSolutions opened this issue · comments

This is a feature request. I'm looking for a way to use the useObserver hook conditionally.

Depending on the state of my component, I'd like to be able to suspend and then resume the useObserver hook.

No hooks can be used conditionally. Use <Observer> component for conditional reactivity.

Also, if you are attempting to optimize by avoiding unnecessary re-renders, consider restructuring your stores so you can control which changes will cause rendering.

@FredyC This is what I had in mind.
https://twitter.com/DavidKPiano/status/1228700861024604160
Is there a way to use hooks such as the useObserver hook in a way similar to "subscribable" objects.
https://codesandbox.io/s/subscribable-context-e4j31

Streams are obviously a whole different paradigm. Feel free to use those or even combine those together (reactions pushing data to streams which you can filter).

MobX is about declarative observability so you never have to doubt that component will be up to date every time. When you introduce conditionals and have a bug in there, it will be really hard to track down.

My advice: Don't optimize before you measure. Unless re-renderings are causing a bottleneck to your app code, it's not worth the trouble.

OK, I'll close this ticket.

Thank you for your answer @mweststrate .

for example observables in unused
branches won't be subscribed to

Could you please explain what you mean by "unused branches" and how they are handled?

@AjaxSolutions I believe he means something like this. To be honest, I did not know about this either. That basically gives you ability for conditional observability.

const store = observable({
  mode: 'in',
  inBranch: 10,
  outBranch: 20
})

export default function App() {
  console.log('RENDER')

  React.useEffect(() => {
    store.outBranch = 30
  }, [])

  return useObserver(() => (
    <div>{store.mode === 'in' ? store.inBranch : store.outBranch}</div>
  ))
}

https://codesandbox.io/s/angry-sunset-doer5?file=/src/App.js

Note: initial 2 renders is normal, happens even if you comment out mutation

Very interesting. Thank you for the codesandbox @FredyC .