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

Late attachment of Downgraded plugin does not clean up the caches #101

Closed
meerkat-citronella opened this issue Sep 15, 2020 · 14 comments
Closed
Labels
bug Something isn't working

Comments

@meerkat-citronella
Copy link

meerkat-citronella commented Sep 15, 2020

I am trying to do something very simple and what I consider intuitive... I am trying to create a global state which is an array of objects, and then tap into it later, getting and setting that global state. Problem is I'm not able to get() the value of this state, let alone set() it.

I have this:

import { createState, useState } from '@hookstate/core'

interface KeyValues {
  [key: string]: string; //e.g. "Date": "7/5/2015"
}

interface KeyValuesByDoc {
  docName: string;
  docType: string;
  docID: string;
  keyValuePairs: KeyValues;
  interpretedKeys: KeyValues;
}

const getKeyValuePairsByDoc = (): KeyValuesByDoc[] => {
...
...
return docData 
}

export const globalDocData = createState(getKeyValuePairsByDoc())

...
...
...

// in a component, 
const docData = useState(globalDocData)

console.log(docData.get())
// => TypeError: docData.get is not a function

Now I understand that this isn't necessarily the right way to access the state of an object... even following the docs, the example given doesn't work:

const exampleObjectData = { a: 1, b: 2 }
const globalExampleObject = createState(exampleObjectData)

....
...
...

// in a component 
const exampleState = useState(globalExampleObject)
console.log(exampleState.keys)
// => Proxy{} 
// expected output: [a, b] per the docs

Really simple question... how can I 'get' the state value of an array of objects? Can I not just get it... do I have to map it first? Why isn't it as simple as just doing .get() like for primitives?

I also tried the fix mentioned in this thread...

import { Downgraded } from '@hookstate/core'

// in a component
const exampleState = useState(globalExampleObject)
console.log(exampleState.attach(Downgraded).get())
// => TypeError: exampleState.attach is not a function
@avkonst
Copy link
Owner

avkonst commented Sep 15, 2020

What you do should work.
Are you sure you use useState from Hookstate but not from React package?

@meerkat-citronella
Copy link
Author

Are you sure you use useState from Hookstate but not from React package?

Yes.

The solution I've come up (kinda hacky) is to convert my object to a string when setting, and parsing as JSON after getting... so the whole thing is just a string and behaves with the rules of primitives.

@avkonst
Copy link
Owner

avkonst commented Sep 16, 2020

const exampleState = useState(globalExampleObject)

What is the result of Object.keys(globalExampleObject) and Object.keys(exampleState)?

Can you post the screenshot of object inspection for both variables?

Can you create a separate repository with a reproducer?

What you see is abnormal. Something strange with your environment.

@meerkat-citronella
Copy link
Author

Here is a code sandbox with the issue recreated. I wasn't able to recreate what I'm seeing in my app in the sandbox.

I realized I was running v2.0.1... upgraded to v3.0.1. This didn't solve the issues, but it prevent them from causing breaking errors. Here are screenshots from my app:

Creating the state:
Screen Shot 2020-09-16 at 3 27 44 PM

Using the state in a component:
Screen Shot 2020-09-16 at 3 27 57 PM
Screen Shot 2020-09-16 at 3 28 13 PM
Screen Shot 2020-09-16 at 3 28 45 PM

As you can see, the attach() and get() methods are no longer throwing errors, but they are still returning the proxy instead of the actual object.

@avkonst
Copy link
Owner

avkonst commented Sep 16, 2020

The sample in codesandbox works fine. And I tested get methods and attached downgraded also makes an effect there. The only weird thing about the codesandbox is that it can not show proxies in the log console properly. It shows null instead. But I guess it is because the browser does not let javascript to inspect objects behind the proxy (which is expected and correct).

If you see different behaviour in you app, could you please commit it to the repository which I could clone and install?

@meerkat-citronella
Copy link
Author

The code is ensconced in our app and would be difficult to extricate and push to a repo... so, apologies, i can't provide the code for you to review. But thank you for your prompt replies and help with the issue.

@avkonst
Copy link
Owner

avkonst commented Sep 16, 2020

I understand why you still see the proxy after the Downgraded().

Remove these lines:
image

And you will see no proxy after downgraded.

The get() caches return value. This might be considered as a bug. I will think if it can be fixed. Current workaround is to attach Downgraded straight after useState call

@avkonst avkonst reopened this Sep 16, 2020
@meerkat-citronella
Copy link
Author

This worked! thanks!

@avkonst
Copy link
Owner

avkonst commented Sep 18, 2020

Keep it open. I will try to fix it so the order does not change the behaviour

@avkonst avkonst reopened this Sep 18, 2020
@avkonst avkonst added the bug Something isn't working label Jan 29, 2021
@avkonst avkonst changed the title unable to get() state of an object Late attachment of Downgraded plugin does not clean up the caches Jan 29, 2021
@TroyJoachim
Copy link

@avkonst
Were you about to find a possible fix of this. I would like to keep the proxy type on there so I get the performance benefits, then remove it right before I post to my api.

@avkonst
Copy link
Owner

avkonst commented Feb 16, 2021 via email

avkonst added a commit that referenced this issue Feb 17, 2021
@avkonst
Copy link
Owner

avkonst commented Feb 17, 2021

Fix released in 3.0.6

@avkonst avkonst closed this as completed Feb 17, 2021
@adrianoos
Copy link

Hello

It might be something simple ... but i can't access my nested state
I'm using - "@hookstate/core": "^4.0.0",

I created a state with hookstate({
value1: '',
value2: ''
etc
})

When my app starts it sets
globalState.value1.set(array of Objects)

When I try to access my globalState.value1 it returns a proxy instead of value

image

same with .get()

What am I doing wrong ?

@adrianoos
Copy link

Ok, so I used .get({ noproxy: true }) and it works fine now i have array of objects.

shinyjohn0401 pushed a commit to shinyjohn0401/hookstate that referenced this issue Jan 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants