Redirect from a util function that is called from a client component.
Answered
Forest bachac posted this in #help-forum
Forest bachacOP
Hi everyone. I have a very simple idea but I don't know how to do this in the NextJs.
I have such 'use server' page
Here I add a 'use client' component, where I have button that calls a someFunction on click
I would like to have an API call in that function. And in case if 401 is returned - redirect to the /signIn from that function. It is possible to add the redirect inside the component, but I would like to keep that logic in the function.
How is it possible to add the redirect directly inside the function?
For example, now I call this function
And when I click on the button I get this error:
I have such 'use server' page
'use server'
import ClickButton from '@/components/clickButton';
const TestPage = () => {
return (
<ClickButton></ClickButton>
);
};
export default TestPage;Here I add a 'use client' component, where I have button that calls a someFunction on click
"use client";
import { someFunction } from "@/utils/checkAndRedirect";
function ClickButton() {
const handleClick = () => {
someFunction(true);
};
return (
<div>
<h1>This is a client component</h1>
<button onClick={handleClick}>Redirect to Another Page</button>
</div>
);
}
export default ClickButton;I would like to have an API call in that function. And in case if 401 is returned - redirect to the /signIn from that function. It is possible to add the redirect inside the component, but I would like to keep that logic in the function.
How is it possible to add the redirect directly inside the function?
For example, now I call this function
import Router from 'next/router';
export const someFunction = (condition: boolean) => {
//call api
//then redirect if needed
if (condition) {
Router.push('/account/signin');
}
};And when I click on the button I get this error:
Error: No router instance found.
You should only use "next/router" on the client side of your app.Answered by riský
something like this and server actions could be intresting
// action.ts
"use server"
import {redirect} from "next/navigaton"
export async function redirectLogin() {
redirect("/login")
}
//page.tsx
"use client"
import {redirectLogin} from "./action"
function ClickButton() {
const handleClick = () => {
someFunction(true);
};
return (
<div>
<h1>This is a client component</h1>
<button onClick={handleClick}>Redirect to Another Page</button>
</div>
);
}
export default ClickButton;
export const someFunction = (condition: boolean) => {
//call api
//then redirect if needed
if (condition) {
redirectLogin();
}
};20 Replies
however your "server action" (as you have "use server") doesnt look like server action - but if it was one you can call
redirect from same next/navigation and it will redirect on the client@riský if you are using app dir, you import `useRouter` from `"next/navigation"` (not next/router)
Forest bachacOP
I use the app dir, you are right. This is what I get after import update
and also for your current way of using
someFunction, it wont ever work as you need to have useRouter in the body of the component and the use .push off that - cant just import and use in function@Forest bachac I use the app dir, you are right. This is what I get after import update
yeah see what i just wrote ^
component being
ClickButtonForest bachacOP
Okay. I see.
It's better to describe what I try to achieve.
It's possible to redirect directly from the component, I got it. But it does not sound very good for me, because it means that I need to move some logic from the function to the component. And in case I need to reuse the function, I need to add the same redirect code there.
So, the idea is to keep the redirect code in function only. Is it possible?
It's better to describe what I try to achieve.
It's possible to redirect directly from the component, I got it. But it does not sound very good for me, because it means that I need to move some logic from the function to the component. And in case I need to reuse the function, I need to add the same redirect code there.
So, the idea is to keep the redirect code in function only. Is it possible?
can you explain your usecase better
like what are you trying to achieve
as i feel like the easiest way for you is just a server action who's purpose is to rediect
Forest bachacOP
Yes, sure
I want to have a fetchServer function, that will make an API call, check the response and if it is 401 - redirect to the signIn page
I want to have a fetchServer function, that will make an API call, check the response and if it is 401 - redirect to the signIn page
@riský as i feel like the easiest way for you is just a server action who's purpose is to rediect
bonus points if your api is that server action
Forest bachacOP
Sorry, fetchClient function*
And the idea is to check the status there and redirect to the signIn page if it is 401. I can do it directly in a component, but it's code duplication every time...
something like this and server actions could be intresting
// action.ts
"use server"
import {redirect} from "next/navigaton"
export async function redirectLogin() {
redirect("/login")
}
//page.tsx
"use client"
import {redirectLogin} from "./action"
function ClickButton() {
const handleClick = () => {
someFunction(true);
};
return (
<div>
<h1>This is a client component</h1>
<button onClick={handleClick}>Redirect to Another Page</button>
</div>
);
}
export default ClickButton;
export const someFunction = (condition: boolean) => {
//call api
//then redirect if needed
if (condition) {
redirectLogin();
}
};Answer
i havent tried, but you may be able to use redirect form next/navigation directly on page but 🤷
(i personally just use server actions for api and if need to login page i redirect there)
(i personally just use server actions for api and if need to login page i redirect there)
Forest bachacOP
Oh, it works
I have to read a little about server actions. Thank you very much!
Could you, please, describe a little how it works?
Could you, please, describe a little how it works?
I see a POST request to a page where I am, and there is a response header x-action-redirect:
So, when the redirectLogin function calls, the browser makes a call to that server action and execute it? Something like that?