Giter VIP home page Giter VIP logo

Comments (15)

onikienko avatar onikienko commented on May 24, 2024

It sounds like you need to useEffect to react on your data changes. Something like that:

// init 
const useCounterStore = createChromeStorageStateHookLocal('myCounter',  0);

// somewhere in the component
const [counter, setCounter] = useCounterStore();

React.useEffect(() => {
    // will fire only when couner changed
}, [counter]);

Be careful if your data is not primitive (array or object). In this case, you will need to avoid running this effect on each component update.

from use-chrome-storage.

spencerc99 avatar spencerc99 commented on May 24, 2024

It sounds like you need to useEffect to react on your data changes. Something like that:

// init 
const useCounterStore = createChromeStorageStateHookLocal('myCounter',  0);

// somewhere in the component
const [counter, setCounter] = useCounterStore();

React.useEffect(() => {
    // will fire only when couner changed
}, [counter]);

Be careful if your data is not primitive (array or object). In this case, you will need to avoid running this effect on each component update.

Hmmm I'm already using a useEffect and its getting run when counter is still the default value

from use-chrome-storage.

onikienko avatar onikienko commented on May 24, 2024

It's how things work in React. useEffect always fires on the initial render. Intentionally.

image
docs

It's out of use-chrome-strage lib topic. But I guess you need to adapt your extension/app logic to be more "react-way".

from use-chrome-storage.

onikienko avatar onikienko commented on May 24, 2024

Regarding your hasLoaded proposal. The fact of state change means that data has loaded.
So you just need to useEffect which depends on the state and design your components accordingly. Keeping in mind React hooks behavior and logic (initial render, shallow compare of non-primitive dependencies, etc).

from use-chrome-storage.

spencerc99 avatar spencerc99 commented on May 24, 2024

I don't think having a concept of hasLoaded is non-reactive. This is a pretty common technique in react to trigger rendering when loading remote data. You have an isLoading state value which you default to true and after an async load process (via useEffect), you can set that to false.

The problem is that the state doesn't change if there is no value already set. The default value is loaded as the default value, so I have no way of telling if the value coming from the chrome storage local hook is before it has been loaded or after it has been loaded.

from use-chrome-storage.

spencerc99 avatar spencerc99 commented on May 24, 2024

The other way I can picture achieving this is something like a whileLoadingValue that you can specify in addition to initialValue. In this case, I might set whileLoadingValue to be null to know that it is still loading. In fetching from the chrome storage, it would either find a value there, or set it to initialValue after it has been loaded.

For example, with a generic async process, this is how I would do that:

const [data, setData] = useState<any[] | null>(null);

async function loadData() {
    const resp = await fetch("https://data-url");
    const data = await resp.json();
    setData(data || []);
}

useEffect(() => {
  void loadData();
}, [])

return data === null ? <div>Loading...</div> : <div>{data.map(renderDataItem)}</div>

from use-chrome-storage.

onikienko avatar onikienko commented on May 24, 2024

Say we have the next hook:
const [value, setValue, isPersistent, error] = useChromeStorageLocal('counterLocal', 0);
In the chrome.storage.local we already have: counterLocal: 10

Changes of value:

  1. undefined on initial component render
  2. value is 0 (set via initialValue of the hook)
  3. useChromeStorageLocal call to chrome API to get the value of counterLocal. value changes to 10

Do you need to know when initialValue was replaced with the value stored in the storage (stage 2 in that example)? Something like isInitialStateResolved?

from use-chrome-storage.

spencerc99 avatar spencerc99 commented on May 24, 2024

Do you need to know when initialValue was replaced with the value stored in the storage (stage 2 in that example)? Something like isInitialStateResolved?

Right exactly! The exact situation is because I'm seeding the value from a remote source. So I have some logic later in the file that is something like (in a useEffect):

// the defaultValue is `null` for ex.
// The problem is that this triggers while the data is loading AND on the initial load when there is nothing in local storage
if (!value) {
  fetchAndSetValue()
}

I basically only want that piece of code to run if and only if we have already loaded from local storage, and found that there is nothing there.

With something like isInitialStateResolved, I could write:

// the defaultValue is `null` for ex.
if (isInitialStateResolved && !value) {
  fetchAndSetValue()
}

from use-chrome-storage.

onikienko avatar onikienko commented on May 24, 2024

Got your point.
It make sense.
Will implement

from use-chrome-storage.

spencerc99 avatar spencerc99 commented on May 24, 2024

great thank you :)

from use-chrome-storage.

spencerc99 avatar spencerc99 commented on May 24, 2024

hi! i saw you made the commit on this, just wanted to check in on when you think it'd be ready to merge? I have a project I'm planning on launching this week that relies on this functionality. Want to check if I need to fork to get in time for my deadline!

from use-chrome-storage.

onikienko avatar onikienko commented on May 24, 2024

I plan to release today.

from use-chrome-storage.

onikienko avatar onikienko commented on May 24, 2024

https://github.com/onikienko/use-chrome-storage/releases/tag/v1.1.0

from use-chrome-storage.

spencerc99 avatar spencerc99 commented on May 24, 2024

thanks! I'm testing this now, and it doesn't ever seem to be setting to complete? any ideas what's going on?

image

this is the code

export const useReviewItemsStore = createChromeStorageStateHookLocal<
  ReviewItem[]
>(StorageReviewItemsKey, []);
  const [
    reviewItems,
    setReviewItems,
    _persistent,
    _err,
    isInitialStateResolved,
  ] = useReviewItemsStore();
  console.log("initial state resolved?", isInitialStateResolved);

from use-chrome-storage.

onikienko avatar onikienko commented on May 24, 2024

Right! I forgot about createHook.... Will review your PR

from use-chrome-storage.

Related Issues (14)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.