Augment react-router module with react-router-relay typings - reactjs

The default react-router is used as such:
import * as React from 'react';
import { Router, Route, hashHistory } from 'react-router';
const routing = (
<Router history={hashHistory}>
<Route path="/login" component={Login}/>
</Router>
};
When I include the "react-router-relay" library, it adds functionality to the Router. Namely it adds 2 properties to the Router component (render and environment):
import * as React from 'react';
import * as Relay from 'react-relay';
import * as useRelay from 'react-router-relay';
import { Router, Route, hashHistory, applyRouterMiddleware } from 'react-router';
const routing = (
<Router history={hashHistory} render={applyRouterMiddleware(useRelay)} environment={Relay.Store}>
<Route path="/login" component={Login}/>
</Router>
};
How would I go about augmenting the react-router typings?
I've tried a bunch of approaches, latest being:
import { Router } from 'react-router';
declare module 'react-router' {
namespace Router {
export interface RouterProps {
environment?: any
}
}
}
As I need to extend the namespace "Router" and the interface "RouteProps" under it.
Link to React router typings: https://www.npmjs.com/package/#types/react-router
The React-router-relay library does not have any typings itself.
All of the information Ive found about this topic:
https://github.com/Microsoft/TypeScript/issues/11034
https://github.com/typings/typings/issues/611
so the problem seems to be that react typings don't ever export the namespaces
so it becomes impossible to augment them

Try this one
declare module 'react-router' {
interface RouterProps {
environment?: any
render?: any
}
}
it's working with the latest react-router definitions.

<Router history={hashHistory} render={applyRouterMiddleware(useRelay)} environment={Relay.Store}>
<Route path="/login" component={Login}/>
</Router>
Looks like login (component={Login}) is not Imported.Hence, It always return an error.

Related

React cannot find exported renderRoutes function

I am working on my first meteor/react application and I am trying to use react-router. However, when I try to run the app, I can't seem to import the renderRoutes function.
I am trying to follow along with the router part here:
https://guide.meteor.com/react.html
The router lives in myapp/client/lib/router.js. Here is my router code:
import React from 'react';
import { Router, Route, Switch } from 'react-router';
import createBrowserHistory from 'history/createBrowserHistory';
import {Home} from '../home/home.js';
import {Login} from '../login/login.js';
import {Connect} from '../connect/connect.js';
const browserHistory = createBrowserHistory();
export const renderRoutes = () => (
<Router history={browserHistory}>
<Switch>
<Route exact path="/" component={Home}/>
<Route exact path="/login" component={Login}/>
<Route exact path="/connect" component={Connect}/>
</Switch>
</Router>
);
I have a meteor.startup() function in myapp/server/main.js, this is all I have in there:
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import { renderRoutes } from '../client/lib/router.js';
Meteor.startup(() => {
render(renderRoutes(), document.getElementById('App'));
});
When I try to run meteor run, here's what I see:
Error: Cannot find module '../client/lib/router.js'
Why? Any help is appreciated!
It is because your router is located in
myapp/client/lib/router.js
whereas your main file is located in
myapp/server/main.js
So unless you intend to implement server-side-rendering, you may move the second code to
myapp/client/main.js
This is due to Meteor's project-structure awareness. If a file is contained in a folder, named client or server it will only be available in this environment.
More to read in the guide: https://guide.meteor.com/structure.html#special-directories

React Router not routing to path specified in Route element

In the following React app w/ two routes the URL http://myapp routes properly to the Layout component. However, the URL http://myapp/login also routes to the Layout component rather than Login. If I change the path="/login" to "/signin" it routes properly to the Login component.
Is there something special about the "/login" path in React Router that routes it to the route? Or is there an error in the way I've setup this routing?
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { Layout } from './components/Layout';
import { NotFound } from './components/NotFound';
import { Login } from './components/Login';
//Redux store
import { Provider } from "react-redux";
import store from "./store";
function renderApp() {
ReactDOM.render(
<Provider store={store}>
<BrowserRouter basename="/">
<Switch>
<Route exact path="/" component={Layout} />
<Route exact path="/login" component={Login} />
<Route component={NotFound} />
</Switch>
</BrowserRouter>
</Provider>,
document.getElementById('react-app')
);
}
renderApp();
So, it appears you have to be careful that the basename attribute is correctly specified for route matching. "/" matches "/login" but "~/" is incorrect. Consider if you need the basename attribute and if so be careful to consider its value.

How to migrate from react-router v1 to v4 ? {this.props.children}

Been trying to migrate from react-dom version 1 to v4.
Since older react-router versions used nested routes it is a little counter-intuitive in v4 since you can basically put <Route />s everywhere. And from official v4 docs it might seem unclear how to migrate this piece - {this.props.children} since it uses history component to use hash portion of the URL.
I thought I had to use <Router history={history}></Router> to get it working in v4. However, <HashRouter></HashRouter> is the way to go with v4 in this case.
Check it out below.
So, to give you a quick example here's what I had in v1:
v1.
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Link } from "react-router";
import Index from './components/Index';
class App extends React.Component {
render() {
return (
<div>
{this.props.children}
</div>
)
}
}
let documentReady = () => {
const reactNode = document.getElementById('react');
if(reactNode){
ReactDOM.render(
<Router history={history}>
<Route component={App}>
<Route path='/', component={Index} />
</Route>
</Router>
, reactNode);
}
};
$(documentReady)
And here's working example of
v4.
import React from 'react';
import ReactDOM from 'react-dom';
import { HashRouter, Route, Switch, Link } from 'react-router-dom';
import Index from './components/Index';
class App extends React.Component {
render() {
return (
<div>
<Switch>
<Route path="/" component={Index} />
</Switch>
</div>
)
}
}
let documentReady = () => {
const reactNode = document.getElementById('react');
if(reactNode){
ReactDOM.render(
<HashRouter>
<Route component={App} />
</HashRouter>
, reactNode);
}
};
$(documentReady)
Note that you have to import HashRouter instead of Router v4, whereas in v1 it was a History, a separate package to be installed along with react-router.
Hope that saves somebody time and
Here's a great resource from François Zaninotto => React Router v4 Unofficial Migration Guide

The prop `history` is marked as required in `Router`, but its value is `undefined`. in Router

I am new to ReactJs. This is my code:
var React = require('react');
var ReactDOM = require('react-dom');
var {Route, Router, IndexRoute, hashHistory} = require('react-router');
var Main = require('Main');
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={Main}></Route>
</Router>, document.getElementById('app'));
and compiling it with webpack. Also I added Main component to my aliases.
The console throws these errors:
I also read these links :
React Router failed prop 'history', is undefined
How do I resolve history is marked required, when value is undefined?
Upgrading React-Router and replacing hashHistory with browserHistory
and many searches around the web, but I couldn't fix this issue. React Router is version 4
If you are using react-router v4 you need to install react-router-dom as well. After that, import BrowserRouter from react-router-dom and switch Router for BrowserRouter. It seems that v4 change several things. Also, the react-router documentation is outdated. This is my working code:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route } from 'react-router-dom'
import App from './components/App';
ReactDOM.render((
<BrowserRouter>
<Route path="/" component={App}/>
</BrowserRouter>
),
document.getElementById('root')
);
Source
Which version of React Router are you using? Router version 4 changed from passing in the browserHistory class to passing an instance of browserHistory, see the code example in the new docs.
This has been catching lots people who automatically upgrade; a migration document will be out 'any day now'.
You want to add this to the top:
import { createBrowserHistory } from 'history'
const newHistory = createBrowserHistory();
and
<Router history={newHistory}/>
If you want to have multiple routes you can use switch like this,
import {Switch} from 'react-router';
then
<BrowserRouter>
<Switch>
<Route exact path="/" component={TodoComponent} />
<Route path="/about" component={About} />
</Switch>
</BrowserRouter>
I got the same problem in ES6, but when I switched to use 'react-router-dom' library, the problem was solved. For all fans of ES6, here we go:
npm install --save react-router-dom
In index.js:
import {HashRouter, Route} from 'react-router-dom';
import App from './App';
ReactDOM.render(
<HashRouter>
<Route path="/" component={App}/>
</HashRouter>
,
document.getElementById('root')
);
Version 4 of React Router changed several things. They made separate top level router elements for the different history types. If you're using version 4 you should be able to replace <Router history={hashHistory}> with <HashRouter> or <BrowserRouter>.
For more detail, see https://reacttraining.com/react-router/web/guides
For (year 2022) version "react-router-dom": "^6.3.0" if anyone is still facing this issue check the order of import in App.js file.
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
I don't know why the order matters but it worked for me.
Also this might help: Attempted import error: 'Switch' is not exported from 'react-router-dom'
I also write a Login practice. And also meet the same question like you. After a day struggle, I found that only this.props.history.push('/list/') can make it instead of pulling in a lot of plugins. By the way, the react-router-dom version is ^4.2.2. Thanks!
handleSubmit(e){
e.preventDefault();
this.props.form.validateFieldsAndScroll((err,values)=>{
if(!err){
this.setState({
visible:false
});
this.props.form.resetFields();
console.log(values.username);
const path = '/list/';
this.props.history.push(path);
}
})
}
The below works for me with "react-router#^3.0.5":
package.json:
"react-dom": "^16.6.0",
"react-router": "^3.0.5"
index.js:
import { render } from 'react-dom'
import { App } from './components/App'
import { NotFound404 } from './components/NotFound404'
import { Router, Route, hashHistory } from 'react-router'
render(
<Router history={hashHistory}>
<Route path='/' component={App} />
<Route path='*' component={NotFound404} />
</Router>,
document.getElementById('root')
)

What should I change in SailsJS router.js to load routes from React-Router file?

What should I change in my config/routes.js file to make it use modules/router files written for the React front-end ?
config/routes.js file:
module.exports: {}
module/router.js:
import React from 'react'
import { Route, IndexRoute } from 'react-router'
import App from './App'
import About from './About'
import Repos from './Repos'
import Repo from './Repo'
import Home from './Home'
module.exports = (
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="/repos" component={Repos}>
<Route path="/repos/:userName/:repoName" component={Repo}/>
</Route>
<Route path="/about" component={About}/>
</Route>
)
I am using webpack, babel for bundling. Really stuck with this.
Currently, the first page is rendered by assets/index.html but if I refresh from any other page (whose address is not /), I get 404 from the server, even though the path is defined in the react router file.
Please help.
EDIT
Here's my index.js file (serves as the React entry point):
import React from 'react'
import { render } from 'react-dom'
import { Router, browserHistory } from 'react-router'
import routes from './routes'
render(
<Router routes={routes} history={browserHistory}/>,
document.getElementById('app')
)

Resources