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

proxy set handler returned false for property "'toast'" #204

Closed
M0hammedImran opened this issue Aug 2, 2021 · 12 comments
Closed

proxy set handler returned false for property "'toast'" #204

M0hammedImran opened this issue Aug 2, 2021 · 12 comments

Comments

@M0hammedImran
Copy link

export interface IStore {
  toast: ToastProps;
  resetToast: () => void;
}

export const store = proxy<IStore>({
  toast: {
    success: null,
    error: null,
    open: false,
  },
  resetToast() {
    this.toast = {
      success: null,
      error: null,
      open: false,
    };
  },
});

image

@dai-shi
Copy link
Member

dai-shi commented Aug 2, 2021

Hey, thanks for trying the library!

this is hard. It doesn't point to an object you are expecting. Would you please try the following?

export const store = proxy<IStore>({
  toast: {
    success: null,
    error: null,
    open: false,
  },
  resetToast: () => {
    store.toast = {
      success: null,
      error: null,
      open: false,
    };
  },
});

@dai-shi
Copy link
Member

dai-shi commented Aug 2, 2021

This is not the first time the error message confuses people. #178

I understand the problem is serious.
To my knowledge, it's hard to detect this at runtime.
But, we don't need to give up. Let's try two challenges.

  1. explore if we can customize the error message (this requires deeper understanding in valtio and proxy-compare)
  2. add a new rule to warn this usage in eslint-plugin-valtio. Though this is valid for some use cases, we can't detect good one and bad one (would be nice if it could).

I'd like to ask for volunteers.
cc @Aslemammad @YPAzevedo @TheEhsanSarshar @israelidanny @a-eid @barelyhuman @lxsmnsyc

@barelyhuman
Copy link
Contributor

I wouldn't mind going through both the recommendations and let you know what my thinking of this is

@etodanik
Copy link
Contributor

etodanik commented Aug 2, 2021

@dai-shi I wouldn't mind playing around with option (1). I think it's a better approach than Option (2) personally both in ease of implementation and practicality (we can't guarantee that someone is running a great & fully functioning linting config)

I'll get back with feedback in the next day or two if nobody gets there before me.

@dai-shi
Copy link
Member

dai-shi commented Aug 2, 2021

@israelidanny I gave up option 1 in a nice way, so it might require some tricks. One thing to note is we don't want to modify proxy-compare for valtio-only problems.

@barelyhuman So, would you primarily take option 2?

I appreciate your helps. Please also refer discussions in #178.

@M0hammedImran
Copy link
Author

This was confusing to say the least. The error was pointing to the store. But it was my fault.
I was trying to call resetToast on snap

const snap = useSnapshot(store);
snap.resetToast();

After that fix. It's been working great.

@dai-shi
Copy link
Member

dai-shi commented Aug 3, 2021

If one prefers using this, they need to make sure calling the method on store not snap.

store.resetToast();

Another discussion in #205.

@M0hammedImran
Copy link
Author

If one prefers using this, they need to make sure calling the method on store not snap.

store.resetToast();

Another discussion in #205.

I made the change. Now I'm using store for mutation and snap for reading and reacting to changes.

@etodanik
Copy link
Contributor

etodanik commented Aug 4, 2021

There is the option of binding all the methods to the correct this while building the snapshot, but it may not be the approach we want here. This way there wouldn't be any error, but it does introduce a little bit of "magic". What do you think @dai-shi @barelyhuman ?

@barelyhuman
Copy link
Contributor

There is the option of binding all the methods to the correct this while building the snapshot, but it may not be the approach we want here. This way there wouldn't be any error, but it does introduce a little bit of "magic". What do you think @dai-shi @barelyhuman ?

While that would help with the developer experience but then we start assuming what the developer wants, someone might use this inside a function and expect this to have a different context, plus the support would then have to be handled for all types of function definitions.

As in, context of this for arrow is going to be different and context for for lamda, named, object method is going to different, I think we'd over engineer it and then call for more problems, I still have to do the above while adding to the linter rules but that is to warn the user of the keyword, and not assume the context of this so it's still a viable solution.

There can definitely be better solutions , i'm open to any. Since I've only written like 2-3 lines on the eslint plugin as of now

@dai-shi
Copy link
Member

dai-shi commented Aug 5, 2021

There is the option of binding all the methods to the correct this while building the snapshot, but it may not be the approach we want here. This way there wouldn't be any error, but it does introduce a little bit of "magic". What do you think @dai-shi @barelyhuman ?

The current behavior is intentional to make it as pure JS as possible.

this on snapshot is useful for getValue function.

const state = proxy({
  count: 1,
  getDoubledCount() {
    return this.count * 2
  },
})

console.log(state.getDoubledCount())

const Component = () => {
  const snap = useSnapshot(state)
  return <div>{snap.getDoubledCount()}</div>
}

This doesn't work if we bind getDobuledCount().

@dai-shi
Copy link
Member

dai-shi commented Oct 23, 2021

option 2 is merged. So, let me close this.

@israelidanny Let us know if you are still working on this.

@dai-shi dai-shi closed this as completed Oct 23, 2021
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

4 participants