geelen / react-snapshot

A zero-configuration static pre-renderer for React apps
MIT License
1.66k stars 105 forks source link

localStorage is not defined. #40

Open sitajaf opened 7 years ago

sitajaf commented 7 years ago

I guess this is due to lack of localStorage support in jsdom.

Starting` crawling http://localhost:59817/ Failed to retrieve initialize state from localStorage: ReferenceError: localStorage is not defined at http://localhost:59817/static/js/main.923fa5f4.js:24:24448 at http://localhost:59817/static/js/main.923fa5f4.js:24:26074 at o (http://localhost:59817/static/js/main.923fa5f4.js:13:23313) at Object.<anonymous> (http://localhost:59817/static/js/main.923fa5f4.js:14:24180) at t (http://localhost:59817/static/js/main.923fa5f4.js:1:107) at Object.<anonymous> (http://localhost:59817/static/js/main.923fa5f4.js:1:505) at t (http://localhost:59817/static/js/main.923fa5f4.js:1:107) at http://localhost:59817/static/js/main.923fa5f4.js:1:195 at http://localhost:59817/static/js/main.923fa5f4.js:1:200 at ContextifyScript.Script.runInContext (vm.js:32:29) Unable to persist state to localStorage: ReferenceError: localStorage is not defined at Array.<anonymous> (http://localhost:59817/static/js/main.923fa5f4.js:24:24646) at d (http://localhost:59817/static/js/main.923fa5f4.js:13:22744) at http://localhost:59817/static/js/main.923fa5f4.js:24:306 at Object.dispatch (http://localhost:59817/static/js/main.923fa5f4.js:24:25796) at t.r.handleLocationChange (http://localhost:59817/static/js/main.923fa5f4.js:23:31542) at t.componentWillMount (http://localhost:59817/static/js/main.923fa5f4.js:23:31796) at c.performInitialMount (http://localhost:59817/static/js/main.923fa5f4.js:21:17205) at c.mountComponent (http://localhost:59817/static/js/main.923fa5f4.js:21:16373) at Object.mountComponent (http://localhost:59817/static/js/main.923fa5f4.js:3:7565) at c.performInitialMount (http://localhost:59817/static/js/main.923fa5f4.js:21:17487) ✏️ Saving / as /index.html

Danjavia commented 7 years ago

I have the same trouble too.

Danjavia commented 7 years ago

:(

arefaslani commented 7 years ago

I have same problem... How to solve this kind of issues?

arefaslani commented 7 years ago

You should not use localStorage instance in the component's render or any method that is evaluated in the server. Move localStorage calls in the componentWillMount method for example. I've solved my problem this way.

Danjavia commented 7 years ago

Thanks @arefaslani I will to try it.

felipedaraujo commented 6 years ago

@Danjavia, did @arefaslani's strategy work for you? I moved my localStorages inside componentWillMount and it still throws the same error, localStorage is not defined. I also tried to use componentDidMount.

stereobooster commented 6 years ago

Jsdom issue won't be fixed, see https://github.com/geelen/react-snapshot/pull/44#issuecomment-341292537. If this answers your question please close issue. Thanks

kostyaVyrodov commented 6 years ago

I have the same issue. As far as I see it the react-snapshot just doesn't have global localStorage, so I'd tried to wrap localStorage and it worked for me.

export const getAuthTokens = () => {
    try {
        // The problem was here
        const tokens = localStorage.getItem(AUTH_ACCESS_TOKEN);
        if (tokens !== null) {
            return JSON.parse(tokens);
        }

        return null;
    } catch (e) {
        console.log(e.message);
        return null;
    }
};

It's not the best solution, but it helped me.

Devilla commented 6 years ago

Did you export this globally? Or inside the component?

Devilla commented 6 years ago

Try this with globals :

"globals": { "window": true, "browser": true, "localStorage":true, }

cesargamboa commented 6 years ago

Use getDerivateStateFromProps, and place the localStorage in there, that worked for me.

yuyuanlin1991 commented 6 years ago

I use localstorage in componentDidMount function,not construction,and solved the error

DonGiulio commented 5 years ago

I had the same error, caused by the credentials verification library. I worked this around this by creating a helper function:

export const storage = () => {
  if (!typeof window.localStorage === "undefined") return window.localStorage;
  else if (!typeof localStorage === "undefined") return localStorage;
  else return false;
};

and checking the availability of localStorage before each call to methods using it:

- verifyCredentials(store);
+ storage() && verifyCredentials(store);
patelrikin commented 4 years ago

I solved it by adding local-storage polyfill for development dependency

npm i -D localstorage-polyfill OR yarn add -D localstorage-polyfill

In your App's index.js file add following: import 'localstorage-polyfill'

This solved error for me.

squeakycheese75 commented 4 years ago

I managed to get this working by extending comments earlier and constructing aalocalStorageWraapper.

const localStorageMock = function () { var store = {}; return { getItem: function (key) { return store[key]; }, setItem: function (key, value) { store[key] = value.toString(); }, clear: function () { store = {}; }, removeItem: function (key) { delete store[key]; }, }; };

const storage = () => { if (!typeof window.localStorage === "undefined") return window.localStorage; else if (!typeof localStorage === "undefined") return localStorage; else return localStorageMock(); };

module.exports = { storage };

I had the same error, caused by the credentials verification library. I worked this around this by creating a helper function:

export const storage = () => {
  if (!typeof window.localStorage === "undefined") return window.localStorage;
  else if (!typeof localStorage === "undefined") return localStorage;
  else return false;
};

and checking the availability of localStorage before each call to methods using it:

- verifyCredentials(store);
+ storage() && verifyCredentials(store);
oseisaac commented 3 years ago

I solved it by adding local-storage polyfill for development dependency

npm i -D localstorage-polyfill OR yarn add -D localstorage-polyfill

In your App's index.js file add following: import 'localstorage-polyfill'

This solved error for me.

I keep getting this error when I import

`TypeError: Cannot set property localStorage of # which has only a getter (anonymous function) node_modules/localstorage-polyfill/localStorage.js:39 36 | } 37 | const instance = new LocalStorage() 38 |

39 | global.localStorage = new Proxy(instance, { 40 | set: function (obj, prop, value) { 41 | if (LocalStorage.prototype.hasOwnProperty(prop)) { 42 | instance[prop] = value`