Using React hooks conditionally in Next JS
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
add a comment |
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
1
The problem here is that React is not up to date. It should be 16.7 alpha. You can check thatReact.version
is 16.5.2. I would expectuseState
to causeundefined is not a function
, I can't say why it saysObject(...)
. 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
add a comment |
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
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
javascript reactjs next.js react-hooks
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 thatReact.version
is 16.5.2. I would expectuseState
to causeundefined is not a function
, I can't say why it saysObject(...)
. 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
add a comment |
1
The problem here is that React is not up to date. It should be 16.7 alpha. You can check thatReact.version
is 16.5.2. I would expectuseState
to causeundefined is not a function
, I can't say why it saysObject(...)
. 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
add a comment |
1 Answer
1
active
oldest
votes
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.
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 expectuseState
to causeundefined is not a function
, I can't say why it saysObject(...)
. 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