Skip to content

‘history’, no-restricted-globals, and window.history

So I was running into an issue with React where if I tried to use ‘history’, my code wouldn’t run telling me it’s an ‘unexpected use of history no-restricted-global’.

I turned to StackOverflow in order to get help and surprisingly, I was able to find an answer to the issue that I was dealing with.

The fix that another use suggested worked great, but now I’m confused as to why it worked in the first place.

Using redux, I called a method via mapDispatchToProps. I needed to throw the ‘history’ in as one of the variables passed in so that I can redirect the user back to the previous page that they were on.

Originally, I tried using just ‘history’ by itself as a variable but I would get a ‘no-restricted-global’ error when I tried to compile so I turned to StackOverflow. This is when they suggested I try using ‘window.history’. I was skeptical at first because I didn’t think something that simple would fix my issue but lo and behold, it compiled successfully.

props.addExperience(data, history);

vs.

props.addExperience(data, window.history);

the window.history works. Can someone please explain why the window.history works but history by itself doesn’t work?

what exactly is ‘history’? what does ‘window’ do that fixes the issue?

edit: this is the original StackOverflow post that I found. While Chasen Bettinger was able to fix the issue, he never really explained why the window. would fix the issue. If someone here can do that, that would be awesome.

Answer

The problem that the linting rule you’re running into is attempting to solve is that implicitly referring to properties on the global object is an easy source of bugs. For example:

var status = false;
if (status) {
  console.log('status is actually truthy!');
}

Here, status on the top level actually refers to window.status, which must always be a string; assigning false to it results in false turning into 'false'.

If status was a restricted global with that rule, you would only be able to use status on the top level if you explicitly referred to window.status. That way, it’s clear that you’re deliberately referring to the global property, and that it’s not an accident.

The same sort of thing is going on when you refer to window.history instead of history. For example, what if, earlier in the code, you defined a variable

var history;

and then used

props.addExperience(data, history);

The linter doesn’t know for sure whether you’re trying to refer to the property on the global object, or if you made a typo. So, the rule is there to get you to explicitly specify that the property is on the window (or to correct the variable name).

As for what window.history actually is, see MDN:

The Window.history read-only property returns a reference to the History object, which provides an interface for manipulating the browser session history (pages visited in the tab or frame that the current page is loaded in).

eg

history.back();     // equivalent to clicking back button
history.go(-1);     // equivalent to history.back();
window.history.go(0); // refresh the current page
history.pushState(stateObj, "page 2", "bar.html"); // add an item to the history state