mobxjs / mobx-react-lite

Lightweight React bindings for MobX based on React 16.8 and Hooks
https://mobx.js.org/react-integration.html
MIT License
2.13k stars 91 forks source link

useObserver won't re-render when store array changes. #261

Closed Suedo closed 4 years ago

Suedo commented 4 years ago

I am trying to create a simple todo list kinda app, where I will type a name of a city, and on clicking an add button, it will update the list of the cities in the UI with the newly added city. But the UI isn't getting updated, and it seems to me like useObserver isn't re-rendering.

Codesandbox here

Can someone please tell me how to fix this :(

danielkcz commented 4 years ago

Fixed version: https://codesandbox.io/s/ts-react-mob-hooks-yge9b (edited only store)

Related issue/comment: https://github.com/mobxjs/mobx-react-lite/issues/174#issuecomment-503909270

Suedo commented 4 years ago

You edited the store, and added the slice() method to the array in CitiesListpart of city.tsx.

Thank you so much for your help! I tried to follow comment #174 but didn't understand much.

If it's not too much trouble, can you please let me know what slice() contributes here?

mweststrate commented 4 years ago

Did you read https://mobx.js.org/best/react? Make sure to read that one first, it probably will answer your question :)

On Wed, Feb 26, 2020 at 9:55 AM Somjit Nag notifications@github.com wrote:

You edited the store, and added the slice() method to the array in CitiesList part of city.tsx.

Thank you so much for your help! I tried to follow comment #174 https://github.com/mobxjs/mobx-react-lite/issues/174 but didn't understand much.

If it's not too much trouble, can you please let me know what slice() contributes here?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/mobxjs/mobx-react-lite/issues/261?email_source=notifications&email_token=AAN4NBDMKXKRFENIQNMIC3TRE2UH7A5CNFSM4K4JPYBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENBHLLA#issuecomment-591558060, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAN4NBFEOITHSC4JF27JPWTRE2UH7ANCNFSM4K4JPYBA .

danielkcz commented 4 years ago

@Suedo Well, slice is one way to "clone" the array. MobX won't be able to track whole array changes unless you have some iteration over those. The linked page by Michel does not really explain this. I don't think we have a good explanation for that anywhere but it's a very repeated question :-|

mweststrate commented 4 years ago

Just checked, the example isn't rendering because you should have used .slice(), but, because the CityView isn't marked as observer. Wrapping that one in observer will fix the issue. The slice() is only needed when you need to pass data to third party components that are not MobX aware so you need unmobxify the data (just as you would call .toJS with e.g. immutable.js. However in your case, it is just as matter of not having made the CityView component MobX enabled.

On Wed, Feb 26, 2020 at 10:46 AM Daniel K. notifications@github.com wrote:

@Suedo https://github.com/Suedo Well, slice is one way to "clone" the array. MobX won't be able to track whole array changes unless you have some iteration over those. The linked page by Michel does not really explain this. I don't think we have a good explanation for that but it's a very repeated question :-|

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/mobxjs/mobx-react-lite/issues/261?email_source=notifications&email_token=AAN4NBGNZJTHDHIDGYAFWDDRE22JBA5CNFSM4K4JPYBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENBM56I#issuecomment-591580921, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAN4NBHHMNQNQB6B2BPWKADRE22JBANCNFSM4K4JPYBA .

mks11 commented 4 years ago

I am wondering if you have an explanation for a derivative code from the "recipe" section of documentation. https://mobx-react.js.org/recipes-migration The part talks about omitting observer from the component when you follow the following pattern. My question is when I have an array, why do I loose the reactivity when I omit the observer wrapper otherwise it's fine? For instance, imagine having an extra property like items array returned by the function from useObserver, and in the store pushing something into it. Thanks a lot.

// use mobx-react@6.1.2 or  mobx-react-lite
import { useObserver } from 'mobx-react' 
function useUserData() { \n
  const { user, order } = useStores()
  return useObserver(() => ({
    username: user.name,
    orderId: order.id,
  }))
}

const UserOrderInfo = () => {
  // this works now just fine
  const { username, orderId } = useUserData()
  return (
    <div>
      {username} has order {orderId}
    </div>
  )
}
danielkcz commented 4 years ago

@mks11 Please open a new issue with reproduction.

mks11 commented 4 years ago

@FredyC thanks. I have a quick question .. is useObserver(()=>({ ... })) like above reactive for observable objects? I have an observable object (from store) that i return from useObserver() where the problem happens.

danielkcz commented 4 years ago

Sorry, but if you have unrelated questions, these are better asked in separate issue with appropriate details.