Using React hooks conditionally in Next JS












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.










share|improve this question




















  • 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.

    – estus
    Dec 30 '18 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?

    – jonhobbs
    Dec 30 '18 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.

    – jonhobbs
    Dec 30 '18 at 14:41











  • Consider updating the question, so it would be more suited to your current problem. I've tried to address it.

    – estus
    Dec 31 '18 at 20:56
















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.










share|improve this question




















  • 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.

    – estus
    Dec 30 '18 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?

    – jonhobbs
    Dec 30 '18 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.

    – jonhobbs
    Dec 30 '18 at 14:41











  • Consider updating the question, so it would be more suited to your current problem. I've tried to address it.

    – estus
    Dec 31 '18 at 20:56














1












1








1


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.










share|improve this question
















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.







javascript reactjs next.js react-hooks






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 12 at 19:44









skyboyer

3,53111128




3,53111128










asked Dec 29 '18 at 18:43









jonhobbsjonhobbs

7,044167198




7,044167198








  • 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.

    – estus
    Dec 30 '18 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?

    – jonhobbs
    Dec 30 '18 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.

    – jonhobbs
    Dec 30 '18 at 14:41











  • Consider updating the question, so it would be more suited to your current problem. I've tried to address it.

    – estus
    Dec 31 '18 at 20:56














  • 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.

    – estus
    Dec 30 '18 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?

    – jonhobbs
    Dec 30 '18 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.

    – jonhobbs
    Dec 30 '18 at 14:41











  • Consider updating the question, so it would be more suited to your current problem. I've tried to address it.

    – estus
    Dec 31 '18 at 20:56








1




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.

– estus
Dec 30 '18 at 8:10





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.

– estus
Dec 30 '18 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?

– jonhobbs
Dec 30 '18 at 12:38





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?

– jonhobbs
Dec 30 '18 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.

– jonhobbs
Dec 30 '18 at 14:41





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.

– jonhobbs
Dec 30 '18 at 14:41













Consider updating the question, so it would be more suited to your current problem. I've tried to address it.

– estus
Dec 31 '18 at 20:56





Consider updating the question, so it would be more suited to your current problem. I've tried to address it.

– estus
Dec 31 '18 at 20:56












1 Answer
1






active

oldest

votes


















1














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.






share|improve this answer
























  • 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.

    – jonhobbs
    Jan 1 at 19:05











  • I seem to have fixed it by putting "if (typeof window === "undefined") return 0;" as the first line in my hook function.

    – jonhobbs
    Jan 1 at 19:45











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53972379%2fusing-react-hooks-conditionally-in-next-js%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














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.






share|improve this answer
























  • 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.

    – jonhobbs
    Jan 1 at 19:05











  • I seem to have fixed it by putting "if (typeof window === "undefined") return 0;" as the first line in my hook function.

    – jonhobbs
    Jan 1 at 19:45
















1














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.






share|improve this answer
























  • 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.

    – jonhobbs
    Jan 1 at 19:05











  • I seem to have fixed it by putting "if (typeof window === "undefined") return 0;" as the first line in my hook function.

    – jonhobbs
    Jan 1 at 19:45














1












1








1







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.






share|improve this answer













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.







share|improve this answer












share|improve this answer



share|improve this answer










answered Dec 31 '18 at 20:55









estusestus

69.6k21102218




69.6k21102218













  • 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.

    – jonhobbs
    Jan 1 at 19:05











  • I seem to have fixed it by putting "if (typeof window === "undefined") return 0;" as the first line in my hook function.

    – jonhobbs
    Jan 1 at 19:45



















  • 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.

    – jonhobbs
    Jan 1 at 19:05











  • I seem to have fixed it by putting "if (typeof window === "undefined") return 0;" as the first line in my hook function.

    – jonhobbs
    Jan 1 at 19:45

















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.

– jonhobbs
Jan 1 at 19:05





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.

– jonhobbs
Jan 1 at 19:05













I seem to have fixed it by putting "if (typeof window === "undefined") return 0;" as the first line in my hook function.

– jonhobbs
Jan 1 at 19:45





I seem to have fixed it by putting "if (typeof window === "undefined") return 0;" as the first line in my hook function.

– jonhobbs
Jan 1 at 19:45


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53972379%2fusing-react-hooks-conditionally-in-next-js%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas