How to programmatically navigate to other page in Next.js? - javascript

After a post request to an external API, I would like to redirect back to the homepage. I do have some knowledge with React and this is my first time using Next.js. Here is the code:
export default function New({genres}) {
const createMovie = (values) => {
console.log(values);
axios.post(`${process.env.NEXT_PUBLIC_BASE_URL}/movies`, {
title: values.title,
description: values.description,
genres: values.genres,
release_date: values.release_date,
cover_url: values.cover_url
}).then(res => {
const router = useRouter();
router.push('/');
})
}
As you can see I used router.push() but I get this error:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
What is the most efficient way to redirect to other pages in Next.js after a function and/or requests?

You need to move where you call useRouter(). You can keep router.push() where it is.
export default function New({genres}) {
const router = useRouter();
const createMovie = (values) => {...}
}
If you look at the Rules of Hooks, you can only call the hook, useRouter() in this case, at the top level.

I also had my initialization of useRouter in my function. I fixed the same bug by placing that line into my function component instead of my function and calling router.push(...) in the function itself.

Related

Errors while building app- Nextjs/Javascript

I got the below errors while building my application. Not sure why this is happening. I wrote a fetch in a sperate function and my trying to call my fetch function (that is styled as a custom react hook) in my getStaticSite props but it is not letting me. How can I bypass this problem? I don't think I'd have this problem if I just wrote the fetch directly into the getStaticSite props, but for organizational reasons I prefer to write my fetches in functions.
The Error I get:
./pages/SSG/paristimeisg.js
6:22 Error: React Hook "useFetchParisTimeISG" is called in function "getStaticProps" that is neither a React
function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use". react-hooks/rules-of-hooks
useFetchParisTimeISG code below
import React from "react";
export default async function useFetchParisTimeISG() {
const response = await fetch(
`https://timeapi.io/api/Time/current/zone?timeZone=Europe/Paris`
);
const currenttimeinparis = await response.json();
return currenttimeinparis;
}
paristimeisg page code below.
import useFetchParisTimeISG from "../../hooks/SSR/ISR/useFetchParisTimeISG";
export async function getStaticProps() {
let mytime = await useFetchParisTimeISG();
return { props: { mytime }, revalidate: 60 };
}
export default function paristimeisg({ mytime }) {
console.log("This is my time", mytime);
return (
<div>
Hello
<h2>{mytime.milliSeconds}</h2>
</div>
);
}
Extra question
I get the same error listed as the above for this page, despite not having any react hooks inside non react components(unless I am missing something?).
Error I get:
./pages/SSG/timeforISG.js
5:16 Error: React Hook "useFetchParisTimeISG" is called in function "timeforISG" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use". react-hooks/rules-of-hooks
Page code
import React from "react";
import useFetchParisTimeISG from "../../hooks/SSR/ISR/useFetchParisTimeISG";
export default function timeforISG() {
let mytime = useFetchParisTimeISG();
return <div>{mytime}</div>;
}
useFetchParisTimeISG code is the same as above (top of page).
Your issue is a simple one - you are incorrectly trying to use a React Hook in a non-React component (getStaticProps, which is a NextJS function).
The solution is simple:
Create a plain old JavaScript file that is not named like a Hook (e.g. parisTimeFetcher.js)
Paste in your original code (with a function name change to avoid a possible React error over the "use" syntax, and remove the React import as it is just plain JavaScript):
export default async function fetchParisTimeISG() {
const response = await fetch(
`https://timeapi.io/api/Time/current/zone?timeZone=Europe/Paris`
);
const currenttimeinparis = await response.json();
return currenttimeinparis;
}
Now, import the function into your Next page, and use this function inside getStaticProps:
import { fetchParisTimeISG } from "../../fetchers/parisTimeFetcher";
export async function getStaticProps() {
let mytime = await fetchParisTimeISG();
return { props: { mytime }, revalidate: 60 };
}
Giving your naming that is prefixed with use, React assumes that you're trying to call a hook with its manageable state outside of a component (which it will not work) thats why it throws this error.
Hooks shouldn't be called inside a regular functions as mentionned in react official Doc
You should change your naming and remove the use Prefix (You dont have to remove it from the the file name but its recommended)

Uncaught (in promise) Error: Invalid hook call. - SPECIAL CASE

I know that hooks cannot be called from functions other than React Functional Components, this is a bit different.
I have created some utility/service type functions that need to use hooks.
// somewhere in services files...
const utilNavTo = (route) => {
const navigate = useNavigate();
...
};
// somewhere in components for screens...
const MyScreen = () => {
...
if(something){
utilNavTo('/somewhere');
}
...
};
// the main app is created with <App /> not App, so that should not be the reason of error
ReactDOM.render(<App />, document.getElementById("root"));
// also App is fully defined with routes having <MyScreen /> defined properly...
When such a function is used within a React Functional Component, I get this error:
Uncaught (in promise) Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
If I call the hook from the react functional component and pass it to the utility function, it works perfectly well.
Is there some way to make this work without passing the hooks as arguments?
I guess it should only fail if the utility function itself is not called from a functional component.
Issue
The issue here is that the code is calling useNavigate in a callback function, conditionally. This breaks the rules of hooks:
Don’t call Hooks inside loops, conditions, or nested functions.
Instead, always use Hooks at the top level of your React function,
before any early returns. By following this rule, you ensure that
Hooks are called in the same order each time a component renders.
Solution
Convert the utilNavTo into a custom React hook that returns a function for a component to use. The hook should be called in the function component body.
Example:
// somewhere in services files...
const useUtilNavTo = () => {
const navigate = useNavigate();
const utilNavTo = (route) => {
...
};
return utilNavTo;
};
...
// somewhere in components for screens...
const MyScreen = () => {
const utilNavTo = useUtilNavTo();
...
if(something){
utilNavTo('/somewhere');
}
...
};

I have this React Invalid Hook Call Error that I'm getting and I wanted to see if I was breaking the rules of hooks or is it something else?

I'm getting the error below.
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
See (link I couldn't add) for tips about how to debug and fix this problem.
You might have mismatching versions of React and the renderer (such as React DOM)
Here is my code. Is it breaking rules of hooks or is the issue something else?
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { useData } from 'useData';
export const checkReference = ({
refId,
}) => {
const data = useData(); //useContext hook
let refData = {};
if (refId) refData = data.getReference(refId);
useEffect(() => {
console.log('INITIAL LOGIC');
if (refData.parameter){
console.log('SECONDARY LOGIC', refData);
}
}, [])
checkReference.propTypes = {
refId: PropTypes.string,
}
checkReference.defaultProps = {
refId: null,
}
}
I am calling it from another file using
checkReference('page-name');
I've got the same issue in my Next.js app. It was a cache related issue. you can try these steps.
Delete node_modules and .next folders
Run npm install or yarn
Start your project again
React hooks are intended to be used inside Functional components like:
export const CustomComponent = () => {}
export function CustomComponent() {}
They cannot be used in normal function because it won't exist inside the context of a React component. If you want to use things like useState or useEffect inside functions defined outside a component, you have to create a custom hook. That is, create a function with the use prefix (e.g. useCheckReference) and then use it like:
export const MyComponent = () => {
const reference = useCheckReference()
}
In that way React knows that that function is presumably gonna be called inside a component and the use of hooks is reliable, also is going to make some optimizations related to hooks and components life cycle.

This custom async hook is not working as expected

I have this custom hook to get the current user from firebase:
import React, { Component, useEffect, useState } from 'react';
import { auth } from "../firebase/auth-service"
const useFirebaseAuthentication = (firebase) => {
const [authUser, setAuthUser] = useState(null);
try {
auth.onAuthStateChanged(async user => {
if (user) {
setAuthUser(user)
} else {
setAuthUser(null);
}
})
} catch (error) {
throw error
}
return authUser
}
export default useFirebaseAuthentication;
When I print on the screen the current user from this custom hook - I get the result as expected.
When I use the hook and try to get the user - I get null.
Can someone point out my mistake?
I don't think that useState here is appropriate, don't you get any console warnings? A hook is just a js function as any other, it's not a React component!
Try to use a local variable instead...
edit
useState is a hook, therefore you should be getting this warning:
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See for tips about how to debug and fix this problem.
It's exactly what's a problem here: you use a hook NOT inside the body of a react functional component, you use it in an ordinary js function.

"Invalid hook call. Hooks can only be called inside of the body of a function component" problem

I get an error in the console as
error!! [Error: Invalid hook call. Hooks can only be called inside of
the body of a function component. This could happen for one of the
following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app*
import firebase from '../../database/firebase';
import { useDispatch } from 'react-redux';
import * as actions from "../../store/actions";
export const userProfilePcture =(id)=>{
const image = firebase.storage().ref(id + '/profilePicture');
var user = firebase.auth().currentUser;
image.getDownloadURL().then((url) => {
user.updateProfile({
photoURL: url
}).then(() =>{
console.log("updete succefully");
updeteUser();
}).catch(error =>{
console.log("error!!",error);
});
});
};
export const updeteUser=()=>{
const dispatch=useDispatch();
var user = firebase.auth().currentUser;
dispatch(actions.updateUser(user));
}
How can I avoid this?
This is the hook you are using:
const dispatch=useDispatch();
You can only use hooks inside a React functional component. Right now you are trying to use this hook in a normal javascript function.

Categories