1

EDIT: This question was originally about a Type error when using React hooks in a CodeSandbox environment but I've updated it so that it's useful to future visitors.

I'm using the following code to try to create a hook for using the scroll position to animate the height of a website header. The trouble is that I've tried various methods to get it to stop it erroring on the server but keep getting various errors (despite checking for the existence of the window object).

There was some example code in my original question and I've updated the following Code Sandbox.

https://codesandbox.io/s/p5y6262qzm

ORIGINAL QUESTION:

Unhandled Rejection (TypeError): Object(…) is not a function

first of all I know that there are other questions with this title but there seems to be multiple causes and I can't find an answer that covers my particular case.

The simplest (incomplete) code I can use to generate the example is this...

import React, { useState, useEffect } from "react";

const useScrollPosition = () => {
  // Store the state
  const [scrollPos, setScrollPos] = useState(window.pageYOffset);

  return scrollPos;
};

export default useScrollPosition;

Although there is a more complete example of what I am trying to do in this codesandbox:

https://codesandbox.io/s/p5y6262qzm

I'm guessing it's something real simple, I just can't seem to put my finger on it.

4
  • 1
    The problem here is that React is not up to date. It should be 16.7 alpha. You can check that React.version is 16.5.2. I would expect useState to cause undefined is not a function, I can't say why it says Object(...). Any way, the problem is codesandbox Next.js template. Commented Dec 30, 2018 at 8:10
  • Ah, of course. That didn't occur to me as my project has the correct version, I was using code sandbox to make a demo to illustrate an unconnected problem when I ran into this. Would you like to convert this to a proper answer or do you think I should just delete the question? Commented Dec 30, 2018 at 12:38
  • Hmm, actually that still doesn't seem to work. I've added two different versions of the alpha , watched it NPM and refreshed the page both times. Commented Dec 30, 2018 at 14:41
  • Consider updating the question, so it would be more suited to your current problem. I've tried to address it. Commented Dec 31, 2018 at 20:56

1 Answer 1

4

This Next.js setup results in

TypeError: window.addEventListener is not a function

error on client side, because window global is shadowed by local variable:

const window = window || {
  width: 0,
  height: 0,
  pageXOffset: 0,
  pageYOffset: 0
};

It should be:

const w = (typeof window !== 'undefined' && window) || {
  width: 0,
  height: 0,
  pageXOffset: 0,
  pageYOffset: 0
};

This will result in mocked object being used during server-side rendering and window being used during client-side rendering.

A better solution would be to avoid using components that are specific to client side, e.g. with react-no-ssr. Since it's not a good practice to apply hooks (useScrollPosition hook) conditionally, it's a component that uses this hook that needs to be rendered conditionally.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks again Estus, I'm pretty sure your answer is correct but it's my fault for not understanding it. the "w" object in your example will either be "true" or {width...}. How do you ensure that the W object is used on the server and the window object used on the client? Sounds simple, but every attempt I've made to do things conditionally on the server has failed. Unfortunately no-ssr is not an option as the component which needs to change height dependent on scroll position is the site header which needs to exist for SEO reasons.
I seem to have fixed it by putting "if (typeof window === "undefined") return 0;" as the first line in my hook function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.