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

Context value populated incorrectly when created using a helper function. #480

Closed
itsgiacoliketaco opened this issue Nov 19, 2022 · 2 comments · Fixed by #488
Closed

Context value populated incorrectly when created using a helper function. #480

itsgiacoliketaco opened this issue Nov 19, 2022 · 2 comments · Fixed by #488

Comments

@itsgiacoliketaco
Copy link

Stackblitz reproduction of error here. My setup uses Vite.

I sometimes use a helper function that wraps calls to createContext. An example is the createContextWithoutDefault function in the Stackblitz. As a consequence of this, Prefresh appears to fill the context with the wrong value when it should instead be empty. For example (as seen in the Stackblitz):

const [ContextA, useContextA] =
  createContextWithoutDefault<string>('Context A Error');
const [ContextB, useContextB] =
  createContextWithoutDefault<string>('Context B Error');

export function App() {
  return (
    <ContextA.Provider value={'Context A'}>
      <Test />
    </ContextA.Provider>
  );
}

Inside <Test />, Context B has the value "Context A"—but a value for Context B was never provided!

I've inferred from looking around the issues here that there is some magic done to uniquely identify each createContext call. I suppose that breaks when you wrap createContext like this. That makes sense, but it's pretty unfortunate, especially because it fails silently. This produced an issue for us that we couldn't repro locally (well at least we couldn't repro it locally in dev mode).

Is there anything that can be done here?

  • Ideally, this "just works" correctly somehow.
  • If not, maybe I can do something inside createContextWithoutDefault to explicitly generate a unique ID for Prefresh?
  • If not that, it would be ideal if Prefresh could warn about this somehow. I'm not sure what the heuristic for warning would be, but perhaps it's as simple as warning any time createContext is called inside a function (as opposed to at the module top level)?

Thanks in advance!

@AleksaStevic
Copy link

I have a similar issue, but I don't use any helper function to create context. Here is more information (reproduction repo, how to reproduce, ...): vitejs/vite#12681

@JoviDeCroock
Copy link
Member

JoviDeCroock commented Apr 2, 2023

This is basically the offending line https://github.com/preactjs/prefresh/blob/main/packages/babel/src/index.mjs#L495 it is used to create an intermediary that is used to maintain the context-value. This because when we have a file like

const x = createContext();

// Do something in a component with context

The value that was updated throughout the lifetime of the application would get lost as createContext gets re-invoked and the closure of the Component would pick up a new context to track. I'm currently thinking about better solutions for this.

One of the things I can see working: #488

The issue you are faced with @AleksaStevic is a bit different as normally we are taking the fileHash into account so that should work out 😅 a workaround here would be to give the variable where you catch the context in a different name. All though if you don't mind, feel free to log out the state.get('filehash') maybe I did something wrong there.

EDIT: yes the fileHash is consistently the same as your files are completely identical 😅

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

Successfully merging a pull request may close this issue.

3 participants