React account activation - reactjs

I'm trying to figure out how to get the account activation link to React.
The Rails API sends an account activation URL as follows:
http://localhost:8080/users/confirm?token=480a476e6be366068dff
I would like to setup a React action that POSTs that token to the API and then a component will render a "account activated" message.
I am currently stuck on 2 issues:
How to directly open the above link in the browser? I'm getting a "Cannot GET /users/confirm" error message. I read that browserHistory is supposed to solve the problem of directly calling React URLs but I'm not sure how to implement it.
How to capture the token from the link? Is "/users/confirm/:token" the correct approach?
routes.jsx:
export default (
<Route history={browserHistory} path="/" component={App}>
<IndexRoute component={HomePage} />
<Route path="/users/login" component={LogInPage} />
<Route path="/users/register" component={RegisterPage} />
<Route path="/users/confirm/:token" component={ConfirmPage} />
</Route>
);

Whatever web server you're using to serve the react code needs to handle that route too. So if you're rendering the html page that bootstraps the react code with rails, add the route to the routes.rb, and have it render the file that loads your bundle.
Now in order to have the token come as a parameter like that:
<Route path="/users/confirm/:token" component={ConfirmPage} />
You'll need to have the rails api direct to it in the same way:
http://localhost:8080/users/confirm/480a476e6be366068dff
If you need to use the query string, update the route in react:
<Route path="/users/confirm" component={ConfirmPage} />
Then in the confirm page, get the token from the query string itself. You can do this in a few ways. I haven't tried it, but I believe react router parses it for you. In the ConfirmPage, access it by:
this.props.location.query.token

Router for Did You have an account? in Material UI ReactJS
handleClickSignIn() {
this.props.history.push("/Register");
}
return(<div><p style={signstyle} > Don't have an account yet?
< a href onClick={this.handleClickSignIn.bind(this)} >Join Register</a>
</p></div>)

Related

React Router match path from query string fallback

I want to be able to serve a React app using React Router both on an Apache and NGINX server without having to change any default Apache/NGINX configs.
The problem is that the application will only be served when you access the root folder, as any sub path leads to a 404 (app.com/ works but not app.com/settings).
For the Apache server, I include a .htaccess file that automatically loads index.html if the requested resource is not found.
For NGINX as far as I understand there is no way to properly load the application in a sub-path unless you change the config file.
My solution for this would be to add the option in the app to store the Router path as a query string, instead of in location.pathname, something like app.com/?page=settings instead of app.com/settings.
Is there any way to add some sort of a middleware in the React router such that when accessing app.com/?page=settings the Router path will be set to /settings. Also, when the user navigates and the router should update the URL in the address bar, it should change it to app.com/?page=user/dashboard instead of app.com/user/dashboard.
I am looking for any solution that would allow the Router to work both with a path and with the path specified as a query string variable.
If needed, here is how my router looks:
<Router history={browserHistory}>
<Route path={BaseRoutes.Home} exact>
<Redirect to={BaseRoutes.Domains} />
</Route>
<Route path={[BaseRoutes.Stats, BaseRoutes.Settings, '/*']} component={SidebarMain} />
<div className={`content-area ${classes.content}`}>
<Switch>
<Route exact path={BaseRoutes.Stats} component={Stats} />
<Route exact path={BaseRoutes.Home} component={Domains} />
<Route exact path={BaseRoutes.Settings} component={Settings} />
</Switch>
</div>
</Router>;
Never mind, I realized I can just use HashRouter instead of Router for NGINX...
So, depending on whether the user's setting of having "pretty" URLs or hash based URLs I can either load the BrowserHistory Router or the HashRouter:
<Router history={browserHistory}> OR <HashRouter>
To switch between them I did:
let SupportedRouter: React.ElementType = HashRouter;
if (MY_CONDITION) {
SupportedRouter = Router;
}
// Render
<SupportedRouter history={browserHistory}>
</SupportedRouter>
I had to cast them to React.ElementType, otherwise optionally passing history lead to TypeScript errors: https://github.com/microsoft/TypeScript/issues/28631#issuecomment-472606019

Using React and Google Hosting, how can I redirect all links that end with /posts/### where ### is any post id

I have a react site that is set up and being used to share deep links into my react native app. That is all working as expected however I'm trying to redirect people who do not have the app installed to the app store / play store.
The url I'm using for deep linking is the following:
https://example.com/posts/###
Is there a way to target all URLs that end with /posts/### and wildcard the id at the end?
Hosted on firebase, built with React.
Thanks!
Using React Router Redirect I was able to solve the issue!
// example
<Router>
<Switch>
<Redirect from="/posts/*" to="/getApp" />
<Route exact path="/getApp" component={GetAppScreen} />
<Route exact path="/contact" component={ContactScreen} />
...
</Switch>
</Router>

Manually entering a url refreshes whole react app

I have a simple react app I'm working on that utilizes react router. My apps starts out of app.js and has the following router setup in app.js:
<BrowserRouter>
<MuiThemeProvider theme={theme}>
<NavigationBar onLogout={self.userLoggedOut} loggedIn={self.state.loggedIn} />
<div className="content-area container-fluid">
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="/login" component={LoginPage} />
<Route exact path="/page1" component={Page1} />
<Route exact path="/page2" component={Page2} />
</Switch>
</div>
</MuiThemeProvider>
</BrowserRouter>
In my app.js constructor, I have console.log to fire off a message to say the constructor was called. Initially I see the message fire off when first coming into the app and then if I use links to navigate between pages I do not see any follow up messages. However, if I go the browser address bar and type in a url manually (http://localhost:3000/login for example), the page loads successfully but have the message from the app.js constructor fire off again. How do you get a react/react-router app to accept manually entered urls the same as links so that the app doesn't reload?
In my app.js constructor, I have console.log to fire off a message to
say the constructor was called. Initially I see the message fire off
when first coming into the app and then if I use links to navigate
between pages I do not see any follow up messages
This is the general behaviour of react app. Very first time you call the link the your app.js enters the tree and it gets rendered. While rendering all lifecycle method including constructor fires in fixed sequence so you are able to see log but when you are changing the link then the component corresponding to route inside is unmounted and component related to new route is rendered and not the complete app.js. This is why you do not see log again.
How do you get a react/react-router app to accept manually entered
urls the same as links so that the app doesn't reload?
You cannot do so because when you are explicitly entering url in address bar then your browser doesnot relate the url with the running web application. It will always render your web application from the beginning. So when it is rendering from beginning you will always get that log.

Routing for external react component/module

I am building an external React component/module that has many sublevels/pages and routes. I am using React Router V4. This component will be imported into a host application that itself has it's own routing system. The host app is also using React Router V4.
The component's root view is a grid view of cards and when the user click one of the cards it brings them to a detail view of the card. When the user is on a detail view, the url in the browser should change so that a user can bookmark the url of that page and visit that page later.
How should the routing work between the host application and the component? Should the host app pass in the route schema into the component or should the component and host app have it's own separate routing system. Does anyone have any examples of this?
React Router V4 plays very nicely in this situation. Both apps would need their own top level Router component in order to be able to run standalone. But you could organize the code so you can reuse the main switch statement for the SubModule. The urls on the host application would all be prefixed with /subModule/, i.e. /subModule/foo, and they would just be /foo on the subModule standalone application.
HostApp.jsx
<Router>
<Switch>
<Route path="/other" component={Other} />
<Route path="/subModule" component={SubModuleRouter} />
</Switch>
</Router>
SubModule.jsx
<Router>
<Route path="/" component={SubModuleRouter} />
</Router>
SubModuleRouter.jsx
<Switch>
<Route exact path="/foo" component={FooComponent} />
</Switch>

React redux routing with hot reloading does not work with refresh

I have the following routes defined
<Route path='/' component={App}>
<IndexRoute component={LoginContainer} />
<Route path='landing' component={LandingComponent} />
<Route path='login' component={LoginContainer} />
</Route>
Now when the user clicks a login button on the loginContainer he is directed to the landing page (from the routes /landing). So now the url changes to
http://server:port/landing
Now if I modify a file and save with hot module reloading (web pack dev server) I get an error saying cannot get http://server:port/landing. This is true because there is no such page, how do I fix this problem.
I am using react-router, react-router-redux, and webpack dev server.
You need to enable historyApiFallback in your webpack dev server config.
This will redirect to the index page on a 404 and consequently allow the router to kick in to find your subroute.
For more info for why this is necessary, or some other, more indepth wy around it, see this answer.

Resources