mobxjs / mobx-react

React bindings for MobX
https://mobx.js.org/react-integration.html
MIT License
4.85k stars 350 forks source link

mobx-react 6 #640

Closed mweststrate closed 5 years ago

mweststrate commented 5 years ago

Things to be addressed:

urugator commented 5 years ago

I don't see the need for making it more complicated than:

const {
 timerStore: {
  timer,
  reset,
 }
} = useStore();
danielkcz commented 5 years ago

@simo-eskalera Please check new documentation site, especially this explanation might interest you: https://mobx-react.netlify.com/recipes-inject#why-is-inject-obsolete

simo-eskalera commented 5 years ago

@FredyC Thank you, the new site looks neat. Glad to see an example of useStore. I apologize if it's already covered, but the page could perhaps be expanded to cover examples with multiple stores. Also, on an unrelated note: you might want to add a tabbed views for JS vs TS sample codes.

@urugator Thanks, I agree with the simplicity part. If you see my linked demo, I'm also exporting useStoreContext() which works exactly like your deconstruction example. However, I feel that useStoreContext() might be a better name for your example, because you're obtaining the context value, not necessarily one store. If you pass multiple stores to the context then useStore without parameter is technically inaccurate, unless you call it useStores.

I see value in having a useStore(<name>) hook and specifying the store by name, for the following reasons:

danielkcz commented 5 years ago

As the name implies, It returns exactly one store (singular form), not all the stores.

It also kinda implies that you have some huge stores so it's sufficient to get one. I am rather splitting my stores by domain and it's very common to be accessing multiple of them in a single component.

const { timerStore } = useStore() does not warn you if a store doesn't exist.

Use the TypeScript and it will warn you before you manage to blink ;)

but the page could perhaps be expanded to cover examples with multiple stores.

I don't think it's that common. Multiple stores would mean multiple Contexts and Providers and that's not something you want to do often to bloat your tree. The original inject had multiple stores, but they were all tied together within a single object. It's a bit of sham :) It forced you to always specify a single store and you weren't able to get more than one. I hated it very much.

Also, on an unrelated note: you might want to add a tabbed views for JS vs TS sample codes.

I don't think so, TS is not so horrible to look at and you might even learn to love it over time :)

simo-eskalera commented 5 years ago

Thanks @FredyC As far as I know, my interaction with MobX was always with multiple stores. I get that they all have one root, but my provider looks like this: <MobxProvider {...stores}> and my injects accept arrays of store names. Are you saying this is was never the proper way? Following the new React patterns for hooks, I think:

const authStore = useStore('authStore')
const userStore = useStore('userStore')
const collectionStore = useStore('collectionStore')

Looks a lot like:

const [count, setCount] = useState(0)
const [users, setUsers] = useState([])
const [expanded, setExpanded] = useState(false)

That is one hook per state, or one hook per store. There's even another state management that does this exactly the same way. So it's not just me! It might be good for inspiration: https://github.com/ctrlplusb/easy-peasy#usestoremapstate-externals

I don't think so, TS is not so horrible to look at and you might even learn to love it over time :)

I've used TS before and understand the benefits of statically typed languages. I'm not saying it's bad or that I don't understand it :) I'm only saying that other libs take the extra step of partitioning their docs sample code and that might be an idea you might want to borrow. See an example here: https://material-ui.com/demos/app-bar/ . Otherwise, it's was a free tip, not a complaint. I like the upcoming docs.

danielkcz commented 5 years ago

but my provider looks like this: <MobxProvider {...stores}>

You can certainly do that with Context as well, it's up to you how you build it up.

const MyProvider = ({ ...stores, children } => {
  return <context.Provider value={stores}>{children}</context.Provider>
}

And why do consider this a bad pattern? It's so nice and concise, you don't have to repeat the store name twice. I really wouldn't relate this to React.useState, those are completely different things.

const { authStore, userStore, collectionStore } = useStore()

Ultimately the general idea is that you can use it however you like. The Provider/inject was very opinionated and has forced to a particular pattern.

Either way, if you have more questions, please use other communication channels. This issue is for purposes of MobX6.

mweststrate commented 5 years ago

Released 6.0.0!

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs or questions.