rehooks / local-storage

React hook which syncs localStorage[key] with the comp.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

setup with Gatsby

joeynimu opened this issue · comments

Hi Guys,

Thank you for this package. I am trying to use it in a Gatsby project and I am getting this error when I start my server;

 2 | Object.defineProperty(exports, "__esModule", { value: true });
  3 | const react_1 = require("react");
> 4 | class LocalStorageChanged extends CustomEvent {
    | ^
  5 |     constructor(payload) {
  6 |         super(LocalStorageChanged.eventName, { detail: payload });
  7 |     }


  WebpackError: ReferenceError: CustomEvent is not defined

Any ideas how I can set this up and fix it?

commented

This is due to the SSR; It is running on node and does not have access to the browser's window object which contains the CustomEvent function. According to this we should patch it, but I'm weary of their idea that all React developers must patch all of their code to check if the window object exists. The window object existing is something that a lot of developers should be able to safely expect when writing code for the browser. Jest runs on node as well, but uses jsdom to alleviate issues such as this.

For the time being, I would look into seeing if react-loadable is of any help.

I will poke around Gatsby and check if there is anything that can realistically be done to alleviate this issue from their side. It would help a lot of people considering how many issues pop up related to this.

@jharrilim Makes sense just what I thought it was. I am trying to add a custom webpack config to replace @rehooks/local-storage with a dummy module but I am getting the same error which depicts that the module isn't being replaced. Below is the code I am using in my gatsby-node.js file.

exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
  if (stage === 'build-html') {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: /@rehooks/local-storage/, // how should i match the module on here??
            use: loaders.null()
          }
        ]
      }
    });
  }
};

Seems I am not smart enought to know regular expressions.

commented

Give this regular expression a shot: /^@rehooks\/local-storage$/

I am also bad at regular expressions, but I like to use regex101 to try them. I also like how it gives a description of what each part does.

@jharrilim thanks I had tried /@rehooks\/local-storage/which worked I guess /^@rehooks\/local-storage$/ would work too. I saw you posed a question for the gatsby folks here Hope something can be implemented to handle this for it seems like it's a pressing issue for lots of guys. And checking if typeof window !== 'undefined' isn't a clean way of handling this issues. Anyway, thanks for the awesome library and I will close this for now. Cheers!

Ran into this issue running this using NextJS... I guess it makes sense... going to have to figure something else out. =(

commented

I have made an example for how you may alleviate this:

https://github.com/jharrilim/if-browser-component

it's also available on npm, but it's simple enough to just remake.

@jharrilim That doesn't solve the issue, which is in the actual compile time imports. Try creating a test project with nextjs and you'll see.

CustomEvent is not defined
ReferenceError: CustomEvent is not defined
    at Object.<anonymous> (/project/node_modules/@rehooks/local-storage/lib/local-storage-events.js:12:35)
    at Module._compile (internal/modules/cjs/loader.js:774:30)
commented

I have tried out using next's @next/dynamic and unfortunately i haven't gotten it to work. My solution did not work either, and neither did this https://github.com/kadirahq/react-no-ssr. Turns out this one is fairly tricky. I will keep playing around to see what will work.

commented

Tried this out with dynamic imports as well and I could not make it work: https://github.com/rehooks/local-storage/blob/ssr_testing/src/use-localstorage.ts

I just got it to work with something like this:

       const [id, setId] = useState('');

	useEffect(() => {
		if (typeof window !== 'undefined') {
			if (id) {
				const {writeStorage} = require('@rehooks/local-storage');
				writeStorage('thing', {id: id});
			}
		}
    }, [id]);

super ugly, but works and typesafe.

I have not tried, but maybe you can isolate the contents of useEffect in some kind of util, and just require it?