Redirecting in react-router-dom v6 in a non-JSX context - javascript

I'm trying to redirect a user from the route they are currently looking at to another route programatically. In my case, I am not in a JSX environment, and cannot use any kind of React hooks. How would I go about this?
I tried to use the code block below to redirect (tried using JSX), only to realize that it wouldn't work as it isn't in the context of the root router.
ReactDOM.render(<div>
<Navigate to="/" />
</div>, document.getElementById("redirect"));
I also want to try and redirect without using window.location.href = as that would cause the whole page to refresh, something I don't want to happen.
EDIT: As requested, I am trying to redirect to a page from an event that is emitted by Tauri and is handled by some TypeScript code on the front end. Using window.location.href isn't an issue in any case.
Here is an example of what I'm trying to do:
/**
* Sets up event listeners.
*/
export async function setupListeners() {
console.log("Setting up link event listeners...");
await listen("deeplink", onLinked);
}
/**
* Invoked when a deep link call is received.
* #param event The event.
*/
async function onLinked(event: Event<string>) {
const { payload } = event;
if (payload == "test:")
// redirect("/testPage");
}

See redirect:
import { redirect } from "react-router-dom";
const loader = async () => {
const user = await getUser();
if (!user) {
return redirect("/login");
}
};
(from the docs)

Related

How to create a root component for making a request regardless of page url in next.js?

I am currently trying to make a request to server after refreshing page or opening this in a new tab.
For example after using f5 I want to make a request. But I don't want to make a request after every routing.
Basically after refreshing I want to make a request to see if user is authenticated using cookie on the request.
But It appears next.js doesn't have a root component like pure react.js(App.js). I searched documentations and different websited. But I couldn't find it. I don't want to write request code to every file.
Here is my files:
Is there a way to do this?
I want to do a request on every link possible (/login, /register, /profile, /) So I need a root component which is mounted on every link (only once).
You need to create _app.ts file in your pages directory. and add the following snippet.This component is the root component in next js and it any function you write here will be executed once depending on how you call this function.
for more info, check this link in Next Js docs https://nextjs.org/docs/advanced-features/custom-app
// import App from 'next/app'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
// Only uncomment this method if you have blocking data requirements for
// every single page in your application. This disables the ability to
// perform automatic static optimization, causing every page in your app to
// be server-side rendered.
//
// MyApp.getInitialProps = async (appContext) => {
// // calls page's `getInitialProps` and fills `appProps.pageProps`
// const appProps = await App.getInitialProps(appContext);
//
// return { ...appProps }
// }
export default MyApp
You can build a function to wrap around your "normal" pages to use it. You can pass arguments, in my example a country option.
export default function Layout(
{country, children}: PropsWithChildren<{country: Country }>) {
/* your code inside here */
return (
<main className={country} data-gtm-block="main">
{children}
</main>
);
}
and then use it like that for every page
export default function AboutPage({ country }: { country: Country }) {
return (
<Layout country={country}>
/* your code in here */
</Layout>
);
}
export const getStaticProps: GetStaticProps = async (context: GetStaticPropsContext) => {
const country = getCountry(context.locale);
return {
props: {
country
}
};
};

getServerSideProps doesn't work redirect for all pages

I wan't for all pages if I has not token then redirect to /login
in _app,js file I added
export const getServerSideProps = async () => {
return {
props: {},
redirect: { destination: "/login" },
};
}
Then I run npm run build and start but getServerSideProps redirect dont wok for any pages
Maybe I created incorrect build not in
prod mode ?
Unfortunately, getServerSideProps is not supported in _app file right now. You can check this document for the reference.
But we can achieve the same thing with getInitialProps
App.getInitialProps = (ctx) => {
//TODO: Check authenticated value in cookies or somewhere in your code
const isAuthenticated = false
if(!isAuthenticated) {
if(typeof window === 'undefined'){ //server-side rendering
res.redirect('/login')
res.end()
return {}
} else { //client-side rendering
Router.push('/login')
return {}
}
}
return {
props: {}
}
}
Following this document again
Adding a custom getInitialProps in your App will disable Automatic Static Optimization in pages without Static Generation.
You need to consider this trade-off too.
If you want to handle it without these side effects. I'd suggest you use Context API. Your _app.js may be like this
const App = ({ Component, pageProps }) => {
return <AuthenticationProvider>
<Component {...pageProps}/>
</AuthenticationProvider>
}
After that, you can do some redirection stuff inside AuthenticationProvider that will apply to all pages
you don't need to use this for hard coding the "/login" you can easily write it in your component, the point of the getServerSideProps function is to fetch data from the backend and preload the data

NextJs GetServerSideProps after update how can i call?

Below I am pulling all the data from the database. But let's say I deleted one piece of data. How can I retrieve the renewed data? How can I run it again?
export async function getServerSideProps() {
const res = await fetch(`http://localhost:8000/api/getAllShipmentTypes`);
const shipmentTypes = await res.json();
return {
props: { shipmentTypes } // will be passed to the page component as props
};
}
But let's say I deleted one piece of data. How can I retrieve the renewed data?
I think you will need to define what is the trigger for the deletion, I can think of these two.
Another action user performs on a page.
Some other system modifying the database that this client application shows.
For #1, To the action, say a button click you can use a router object to set the same route again which will run getServerSideProps again
When you request this page on client-side page transitions through next/link or next/router, Next.js sends an API request to the server, which runs getServerSideProps
For #2 - this would be handled by giving the user an option to refetch the data from the server again using a link or router component
You can do something like:
import { useRouter } from 'next/router';
function SomePage(props) {
const router = useRouter();
// Call this function whenever you want to
// refresh props!
const refreshData = () => {
router.replace(router.asPath);
}
}

ReactJs - redirect url

I am new to reactjs - and if I hit an error page on a subpage - because the url is wrong - I am looking to find a way to redirect the page to another.
So de/dienstleistungen/isdfisf -- spelt wrong
redirect to de/dienstleistungen
I've tried to write a function to handle this but no luck
if (!lang.serviceIntro[0][service]) {
console.log('undefined', this)
this.context.router.push('/de/dienstleistungen')
}
Failed context type: Invalid context router of type object supplied to PlainHeader, expected function.
are you using react-router? and if used which version are you on it?
Check out https://reacttraining.com/react-router/web/api/history which is currently on v4. This is my code
class App extends Component {
componentDidMount() {
let token = ... // achieve token
if (!token) {
this.props.history.push('/login');
}
}
render() {
....
}
}
my code in main page checking if not authenticated will redirect to login page programmatically. Props this.props.history will be passed by react router through .
Check the docs above for more information. Hope it help
As the error message says, you should declare contextTypes.router as an object, router was a function in older versions
static contextTypes = {
router: PropTypes.object.isRequired
}

React/Redux app actions not being dispatched properly

I'm trying to set up my first React app using Redux, but I'm currently having some issues with dispatching actions. I have the following files for my actions so far:
constants/AuthActionTypes.js:
export const AUTH_PENDING = 'AUTH_PENDING';
export const AUTH_SUCCESS = 'AUTH_SUCCESS';
export const AUTH_FAIL = 'AUTH_FAIL';
actions/AuthActions.js:
import * as AuthActionTypes from '../constants/AuthActionTypes';
function authPending() {
return { type: AuthActionTypes.AUTH_PENDING };
}
function authSuccess(response) {
return { type: AuthActionTypes.AUTH_SUCCESS };
}
export function login(username, password) {
return dispatch => {
dispatch(authPending());
// nothing really happens yet
dispatch(authSuccess());
};
}
I've also got a login component containing an HTML form, and a login function that gets called when the form is submitted.
components/Login.js
...
login (e) {
e.preventDefault();
var username = ReactDOM.findDOMNode(this.refs.username).value;
var password = ReactDOM.findDOMNode(this.refs.password).value;
this.props.dispatch(AuthActions.login(username, password));
}
...
The function is triggered, but... something isn't right. I use redux-devtools, and it only dispatches a single action - surely, it should dispatch the actions from both authPending and authSuccess? In addition, the devtools pane doesn't display any action type, and I get the following warning in the console:
Warning: Failed propType: Invalid prop action of type function
supplied to LogMonitorEntry, expected object. Check the render
method of LogMonitor.
What am I doing wrong here? What have I missed? I've primarily looked at the examples at https://github.com/rackt/redux/tree/master/examples/real-world and https://github.com/yildizberkay/redux-example, and I can't see what I'm doing differently that makes my own app break.
... and a couple of minutes later, I've stumbled across the answer: I didn't have the redux-thunk middleware applied to my store. Applied that, and everything works as expected.
You can do w/o thunk.
change
this.props.dispatch(AuthActions.login(username, password));
to
this.props.dispatch(AuthActions.authPending());
this.props.dispatch(AuthActions.authSuccess());
Ofcourse, you have to import those two methods/action-creators.

Categories