I am currently developing a website where I have used react, react-router and redux. We are doing Server side rendering and using react router on server as well. Now I have a case where i want client side to render different component than server side. I want like this.
Client Side
<Route path="welcome/:id" component={Home} />
Server Side
<Route path="welcome/:id" component={App} />
I have use case like when user click's an image i want to open a modal with contents and recommend images . when user click's on recommended images same modal should fill up the details and i want to change the route as well. Same route when opened in new window should open an html page for facebook and google to scrap meta tags from it.
So either I render different component on client and server. But that too has a problem because then i need to find a way to turn off client side react router when server is serving the rendered page.
Or in client side generate a pseudo route change which changes url but doesn't render a component.
Check if window is present and conditionally set the component you want to use like this:
let Handler;
if (typeof window !== 'undefined') {
Handler = Home;
} else {
Handler = App;
}
return <Route path="welcome/:id" component={Handler} />
The troublemaker in me wants to know why you're doing this :)
check process.env.Browser
let Handler;
if (process.env.browser) {
Handler = Home;
} else {
Handler = App;
}
return <Route path="welcome/:id" component={Handler} />
Related
I want to create dynamic pages in gatsby but I don't know what the full url name would be.
createPage({
path: '/account/orders/:id',
matchPath: '/account/orders/:id',
component: path.resolve('./src/templates/order.tsx'),
});
I thought the code written would be okay to visit page with any value of 'id' but while building the development bundle it gives an error
account\orders\:id contains invalid WIN32 path characters
The ':id' value can be anything so I dont want to use looping method to create the page. What could be done?
Taking into account that:
You don't want to loop through pages
You will never know the value of the id
Your only chance is to use client-only routes through the file system route API.
In your case, assuming that your "unknown" page will be under /account/orders you should create a folder structure such: src/pages/account/orders/[...].js. The [...].js notation stands for the file system route for an undefined value.
In the [...].js file you can just create something like:
import React from "react"
import { Router } from "#reach/router"
import Layout from "../components/Layout"
import Profile from "../components/Profile"
import Default from "../components/Default"
import CustomOrderComponent from "../components/CustomOrderComponent"
const Orders = () => {
return (
<Layout>
<Router basepath="/account/orders">
<Profile path="/profile" />
<CustomOrderComponent path='/:id' />
<Default path="/" />
</Router>
</Layout>
)
}
export default Orders
From the docs:
Briefly, when a page loads, Reach Router looks at the path prop of
each component nested under <Router />, and chooses one to render
that best matches window.location (you can learn more about how
routing works from the #reach/router documentation). In the
case of the /orders/profile path, the Profile component will be
rendered, as its prefix matches the base path of /orders, and the
remaining part is identical to the child’s path.
In the above scenario, CustomOrderComponent will render your variable id (:id).
I'm processing a transaction with Moneris in my React Native app in a WebView. The URL in my WebView contains the credentials of my Hosted PayPage Configuration as URI parameters. When creating that configuration on the Moneris site, I need to provide the URL for the hosted paypage to redirect to once the transaction is complete. When I enter something like https://www.google.ca/ as the callback, it works fine, but I don't know what callback URL I'd need to enter to return to my app.
What I Want To Know:
What is the callback URL I'd need to use in order to return to a React Native app?
WebView is just a component inside your app, so you are never leaving your app. First, confirm that page is rendered in a WebView as opposed to launching browser as a separate app and opening a page there (in this case you can't go back to your app programmatically). Then, if you are actually using a WebView component, you could, for example, do the following: add NavigationState listener to your WebView, and read the url the WebView navigates to and take action accordingly
class MyComponent extends React.Component{
onNavigationStateChange = (navState) => {
if (navState.url === 'https://www.yoursite.com') {
// user just got redirected to requested site
// do something in react-native app now, for example
// close this component and show another one
}
}
render(){
return <View>
<WebView
...
onNavigationStateChange={this.onNavigationStateChange}
/>
</View>
}
}
I am new to react-router-dom and web development. I am creating a PWA on mobile browser, I could not find a way to navigate the user to exit the app like in native mobile app
what happened was the page was navigating over and over again until it hits the last stack of the history then it will close the app
I know how to listen to route changes, how do I force user to exit the app if they're in a specific route without going back to previous history
It depends on what do you mean by "forcing a user to exit the app"?
What is the trigger and what the effect?
Trigger can be button click for example, and effect can be redirect.
let's say that the auth user on route { /app } and by clicking -
import { Redirect } from 'react-router-dom';
<button
onClick={()=> <Redirect to="/" }
/>
But from your question it sounds like you want to use your location as trigger and do something according to that (if you don't familiar with hooks it can translated to componentDidMount/Update) -
React.useEffect(()=> {
if (props.location.pathname === '/') {
// Do Something here...
}
}
,[props.location])
Here is the full { location } react-router doc https://reacttraining.com/react-router/web/api/location
Do notice that { location } have
state: {
[userDefined]: boolean
}
method, maybe it will help you with user flow process
I have a react applicatie running in a Amazon S3 bucket, it is available here: This is the homepage of the app, the user can search ships in the search bar.
The app produces a link in the dropdown menu that looks like this:
However when the user clicks on the link you don't see the details page but the user is redirected to this page without CSS.
Locally is everything working fine.
My route component looks like this:
export class Routes extends React.Component {
render() {
return (
<div>
<Route exact path={HOME_PAGE} component={Home}/>
<Route path={HOME_PAGE + "/details/:id"} component={Details}/>
<Route path={HOME_PAGE + "/form/:mode"} component={Edit}/>
<Route path={HOME_PAGE + "/form/:mode/:id"} component={Edit}/>
<Route path={HOME_PAGE + "/csvForm"} component={CsvForm}/>
</div>
);
}
}
I have build a prefix for the HOME_PAGE path that looks like this:
export const HOME_PAGE = (ENVIRONMENT == "DEVELOPMENT") ? "" : "/url"
This sets the homepage path for either development or production environment.
I was thinking of an other way to pass the ship id to the details page, maybe with a GET parameter. So the route will look something like this HOME_PAGE + /details?id=5c335682379b4d7a6ea454a8.
But I don't know if react-router supports that kind of parameter, maybe someone has a beter solution to solve this problem. Just by playing around on the website, I hope I have given enough information to understand the structure of the site.
If you're using react router v4, for every Route that you defined, react-router will pass three props:
Match
Location
History
If you would like to access the params (which is under /:someParams), you can access the Match props by using match.params.someParams
And if you prefer the query string, you can use the Location props by using location.search which is a string so that in your case it'll return ?id=5c335682379b4d7a6ea454a8. You'll have to process the string by using qs to get your id value.
You can see the detail over here: https://reacttraining.com/react-router/core/api/Route/route-props
So in your case this would be the solution:
On your parent
<Route path={HOME_PAGE + "/details"} component={Details}/>
Your your Details Component
import qs from 'query-string'
const Details = ({location}) => {
const {search} = location
const queries = qs.parse(search) // you should have the query string object
return (
<div>{queries.id}</div>
)
}
I wonder what type of navigation works well with login authentication? Right now i use conditional rendering for certain pages or components to display and through
if (this.state.loggedIn) {
return <UI loggedIn={this.state.loggedIn} showUser=
{this.state.showUser} logout={this.logout.bind(this)} />;
};
i can render something after the validation. What would it look like if i wanted to render a couple of more different pages? Should i put a state on each page that will change on onclicks and cause the app to render desired page?
Thank you lads
This is an issue which nearly every modern application must tackle. Because of this, many libraries have already solved these issues for you. Take this code for example which uses react-router:
In my example I am showing you what the routes would look like in a routes.js file and then a separate file for what the acl would look like. The acl is a function which is passed into the onEnter of each route you want to protect. You can call it anything you like.
routes.js
import React from 'react';
import { hashHistory, Router, Route, IndexRoute } from 'react-router';
import { acl } from './util/acl-util';
import AppContainer from './containers/app-container';
import DashboardPage from './pages/dashboard-page';
export default class Routes extends React.Component {
render() {
return (
<Router history={hashHistory}>
<Route path="/" component={AppContainer}>
{/* NON-AUTH ROUTES */}
<Route
path="login"
components={{
main: LoginPage,
aside: null,
header: this.getHeader,
}}
/>
{/* AUTH-REQUIRED ROUTES */}
<Route
onEnter={acl}
path="dashboard"
components={{ main: DashboardPage }}
/>
</Router>
);
}
}
acl-util.js
import { hasAuth } from './auth-util';
export function acl(nextState, replace) {
const { pathname, search } = nextState.location;
if (!hasAuth(theState)) {
window.alert(
'Please Log in!'
);
replace(`/login?loginRedirect=${encodeURIComponent(pathname + search)}`);
}
}
I threw this example together from cutting out part of my code that won't apply directly to this concept - and therefore this code won't run as is. You'll need to define your pages, and set up a store etc.
You'd need to define a hasAuth function which can look into your state and determine whether a user is authenticated. For my hasAuth function I am looking for a jwt token and parsing the date, if the date is still in the future, I know they are still authed and any subsequent rest api calls will work.
I know you weren't asking for a certain library, but I recommend this because the app I took this code from has dozens of routes and the acl function also implements a role matrix which looks at what a user can and cannot do based on their jwt token. Our application is pretty massive and this approach keeps it organized.
Without having something like react-router, you're right, you'd need to manually manage which page is showing and manually check for auth state in each component or make a parent component to do it. In my example the "parent component to manage it" is react-router and my onEnter method called acl. In traditional applications acl stands for access control list - you can expand the code in whichever way you like.
edit:
as someone mentioned in a comment about . Your frontend application is only as secure as the backend service it is grabbing data from or posting data to. In my example, the react code attempts to mirror the auth state in the jwt token. But, at the end of the day, your real security will only be provided by your back end services. Just because the frontend thinks a user can be logged in, shouldn't mean the backend should assume they are - you need backend authentication since all frontend application state can be modified by technical users.