Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onInvalidated not Called when Bad Reference Hits Store - App Crashes - React Native Expo #2212

Open
3 tasks done
ChristopherGabba opened this issue Sep 1, 2024 · 2 comments

Comments

@ChristopherGabba
Copy link

ChristopherGabba commented Sep 1, 2024

Bug report

  • I've checked documentation and searched for existing issues and discussions
  • I've made sure my project is based on the latest MST version
  • Fork this code sandbox or another minimal reproduction.

Sandbox link or minimal reproduction code

  1. Clone this repo: https://github.com/ChristopherGabba/BugHuntingForFrankAndTyler.git
  2. Create expo development build via simulator or via actual device: npx eas build --profile development --platform ios
  3. Run npx expo install -c in terminal
  4. The ignite boilerplate app will open up. Tap Sign in
  5. Go to the Podcasts Tab at the bottom
  6. Tap on any Toggle Favorite button for any podcast. I hard coded this:
export const EpisodeStoreModel = types
  .model("EpisodeStore")
  .props({
    episodes: types.array(EpisodeModel),
    favorites: types.array(
      types.safeReference(EpisodeModel, {
        onInvalidated(event) {
          console.log("INVALIDATED", JSON.stringify(event, null, 4))
        },
      }),
    ),
    favoritesOnly: false,
  })

with this:

    addFavorite(episode: Episode) {
      const bsEpisode: ReferenceIdentifier[] = ["BS_EPISODE_REFERENCE"]
      store.setProp("favorites", bsEpisode)
    },

Describe the expected behavior

I would expect the onInvalidated hook to call and remove the bad reference immediately instead of crashing the app.

I've SEVERELY struggled with this behavior with MST with regard to references, and that's why I migrated to safeReference so that it wouldn't crash. The app should not crash when a bad reference arrives, it should handle gracefully (aka hit the invalidated function call).

Real Life Scenario:

  1. Fetch data from backend
  2. Data was modified by another user (lets say a Todo action and assigned it to another user that isn't in the store)
  3. Fetch data again
  4. Bad reference arrives and app crashes

Describe the observed behavior

The app crashes immediately.

You'll notice after you add the bad reference, the app is stuck in an eternal cycle of instant crashes because the bad reference is just stuck in the store, and it forces the dev to have to clear the store. When you have about 10 reference situations in an app like mine, that is so annoying to have to do.

In my app, what I've had to do is:

    addFavorite(episode: Episode) {
      const bsEpisodes: ReferenceIdentifier[] = ["BS_EPISODE_REFERENCE"]
      // Install a function that parses episodes first and checks for valid references
      const validEpisodes = checkEpisodesForValidReferences(bsEpisodes)
      store.setProp("favorites", validEpisodes)
    },

And I do not enjoy having to do this, and frankly feel as though I shouldn't have to if the onInvalidated function was working correctly. If a reference is bad from the backend, you have to send something to modify the backend to make sure it doesn't just keep hitting the client with a bad reference over and over again, and the onInvalidated hook was where I handle this..

There has to be a better way of dealing with this.

As always, thanks so much for looking into this, I love MST (minus the reference stuff) :)

@ChristopherGabba ChristopherGabba changed the title onInvalidated not called when Bad Reference hits Store - React Native Expo onInvalidated not Called when Bad Reference Hits Store - App Crashes - React Native Expo Sep 1, 2024
@ChristopherGabba
Copy link
Author

ChristopherGabba commented Sep 1, 2024

I ran across a similar issue here: #1509

And I wholeheartedly agree with @jamonholmgren's comment!

@coolsoftwaretyler
Copy link
Collaborator

Hi @ChristopherGabba - thanks for the bug report and I'm sorry for all the frustration.

For what it's worth, I agree that this is a poorly documented part of the codebase, and it's harder than it has to be. I agree with Jamon that we should solve this at a library level.

I am happy to keep this open along with the other issue, and we'll continue to consider how to build a feature that does what you (and many other people) expect.

But I do want to bring up my comment from that thread: #1509 (comment)

Strictly speaking, the behavior is working as intended. I'm not certain if it will make sense to change safeReference behavior, or if we'll need to make a new type of reference.

I think the main problem here is the naming and documentation of this feature makes it seem like it's going to do something very different from what it does in actuality. A safeReference is just a reference that allows you to pass a valid identifier OR the literal value undefined. safeReferences are not something that allow you to pass an invalid identifier, although there is clearly a desire for behavior like that.

The onInvalidated hook isn't for handling invalid references (again, I think the naming is very confusing, haha). Rather, it is a hook for when a previously valid reference is about to be detached or destroyed: https://mobx-state-tree.js.org/concepts/references (search for "onInvalidated")

I don't say that to dismiss the concern. Just to clarify for anyone else who ends up here.

But still, I hear you (and many other folks), that this is a painful experience. I don't have a great estimate on when this will be fixed, or how.

If you're very motivated to have a better experience, I'd be very happy to help you get set up to contribute to the codebase, and I always prioritize community contributions for code review.

Could be a fun way to work together to resolve a longstanding pain point! If that's interesting to you, email me at tyler (at) coolsoftware.dev and I'd even be down to schedule a video call to onboard you.

If you don't have the time or interest, we'll just keep you updated here if and when we get around to figuring this out.

Have a great weekend!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants