I just started with electron and I've been having difficulties integrating react-router with it. I keep on getting this warning whatever I do:
Warning: [react-router] Location "/" did not match any routes
Router:
"use babel"
import React from 'react'
import { Router, hashHistory } from 'react-router'
/* ******************
IMPORTS
*********************/
import {routes} from './routes'
const App = () => {
return (
<Router history={hashHistory} routes={routes} />
);
}
export default App
Routes:
"use babel"
import React from 'react'
import { Route, IndexRoute } from 'react-router';
/* ******************
IMPORTS
*********************/
import App from './src/app.js'
import Root from './src/root'
export default (
<Route path="/" component={Root} />
);
Root:
import React, { Component } from 'react'
export default class Root extends Component {
render() {
return (
<div>test</div>
);
}
}
I noticed that react-router is adding the hashtag before the slash. I am pretty sure that I did a rookie mistake somewhere but I can't find out what's wrong...
URL: file:///C:/wamp/www/electron_projects/projectOne/index.html#/
I have read other similar questions but no luck. Your help would be really appreciated.
Because there is a mismatch between the way you are importing and exporting, use either named or default import/export.
Default import/export:
import routes from './routes';
Define it like this in routes.js:
let routes = (
<Route path="/" component={Root} />
);
export default routes;
named import/export:
import {routes} from './routes';
Define it like this in routes.js:
let routes = (
<Route path="/" component={Root} />
);
export routes;
Since your are returning all the routes by App component, so render that component by ReactDOM.render, like this:
ReactDOM.render(
<App/>,
document.getElementById('app')
);
Read the difference between these two: https://danmartensen.svbtle.com/build-better-apps-with-es6-modules
You are exporting your routes like this:
export default (
<Route path="/" component={Root} />
);
Therefore you need to import them like this:
import routes from './routes'
Default exports are unnamed, and therefore need to be imported without brackets. If you surround it with brackets, it looks for a named export.
Update
It's worth noting that you can import them by any name you choose. It's an unnamed export, so it doesn't matter what you name the import. You could (but wouldn't) import it like this instead:
import foo from './routes'
And it wouldn't make a difference.
You may not be using your Router component in your code, the place where rendering into dom via ReactDOM.
Please check below the working code snippet.
let Router = ReactRouter.Router;
let RouterContext = Router.RouterContext;
let Route = ReactRouter.Route;
const Root = (props) => {
return (
<div>
<h1>test</h1>
</div>
);
};
const routes = (
<Route path="/" component={Root} />
);
const router = (
<Router history={ReactRouter.hashHistory} routes={routes}/>
);
ReactDOM.render(
router,
document.getElementById('test'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/3.0.0/ReactRouter.min.js"></script>
<div id="test"></div>
Related
I am running an issue where, regardless of what URL I am putting into my browser, I keep getting routed to my main page. I've posted the code below for you to take a look, but my goal is to have my browser take me to my drivers.jsx component when the URL is localhost:3000/drivers. Currently, when I go to localhost:3000/drivers, it renders my _app.jsx component instead :(. Can someone help me understand why I can never render the Drivers component (in drivers.jsx) when I am at localhost:3000/drivers?
index.jsx:
import { BrowserRouter as Router, Routes, Switch, Route } from 'react-router-dom';
import MyApp from './_app.jsx';
import Drivers from './drivers.jsx'
import React, { Component } from 'react'
import { Link } from "../routes.js"
class Home extends Component {
render() {
return (
<Router>
<Switch>
<Route exact path='/drivers' element = {<Drivers />}> </Route>
<Route exact path='/' element = {<MyApp />}> </Route>
</Switch>
</Router>
);
}
}
export default Home;
_app.jsx
import React, { Component } from 'react';
import { useLoadScript } from '#react-google-maps/api';
import Map from '../components/map.jsx';
import "../styles/globals.css";
const MyApp = () => {
const libraries = ['places'];
const {isLoaded} = useLoadScript({
googleMapsApiKey: XXXXXXXXXXXXXX,
libraries
});
if (!isLoaded) return <div>Loading...</div>;
return (
<Map />
);
}
export default MyApp;
drivers.jsx
import React, { Component } from 'react';
class Drivers extends Component {
render() {
return (
<div>TEST</div>
);
}
}
export default Drivers;
I've tried putting the routing logic inside _app.jsx instead, but that causes an incredible amount of errors. My thought is index.js should host all the routing logic, but it shouldn't keep rendering MyApp instead of Drivers when the route is "localhost:3000/drivers".
if your react-router-dom version is
6.4.3
then the switch component dosen't work try changing code to this
instead of using Switch. wrap Route inside Routes
<Router>
<Routes>
<Route path='/drivers' element = {<Drivers />}> />
<Route exact path='/' element = {<MyApp />}> />
</Routes>
</Router>
like this
I am trying server side rendering using react-router 4. I am following the example provided here https://reacttraining.com/react-router/web/guides/server-rendering/putting-it-all-together
As per the example on server we should use StaticRouter. When I import as per the example I am seeing StaticRouter as undefined
import {StaticRouter} from 'react-router';
After doing some research online I found I could use react-router-dom. Now my import statement looks like this.
import {StaticRouter} from 'react-router-dom';
However when I run the code I am getting Invariant Violation: Browser history needs a DOM in the browser.
my server.js file code
....
app.get( '*', ( req, res ) => {
const html = fs.readFileSync(path.resolve(__dirname, '../index.html')).toString();
const context = {};
const markup = ReactDOMServer.renderToString(
<StaticRouter location={req.url} context={context} >
<App/>
</StaticRouter>
);
if (context.url) {
res.writeHead(302, {
Location: context.url
})
res.end();
} else {
res.send(html.replace('$react', markup));
}
} );
....
And my client/index.js code
....
ReactDOM.render((
<BrowserRouter>
<App />
</BrowserRouter>
), root);
....
Update v1
Reduced my example to a bear minimum and still getting the same error.
clientIndex.js
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from '../App'
ReactDOM.render((
<BrowserRouter>
<App/>
</BrowserRouter>
), document.getElementById('app'))
serverIndex.js
import { createServer } from 'http'
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { StaticRouter } from 'react-router'
import App from '../App'
createServer((req, res) => {
const context = {}
const html = ReactDOMServer.renderToString(
<StaticRouter
location={req.url}
context={context}
>
<App/>
</StaticRouter>
)
res.write(`
<!doctype html>
<div id="app">${html}</div>
`)
res.end()
}).listen(3000);
App.js
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import routes from "./client/routes";
const App = ( ) => (
<Router>
<Route path="/" exact render={( props ) => ( <div>Helloworld</div> )} />
</Router>
)
export default App;
You need to use different history provider for server side rendering because you don't have a real DOM (and browser's history) on server. So replacing BrowserRouter with Router and an alternate history provider in your app.js can resolve the issue. Also you don't have to use two wrappers. You are using BrowserRouter twice, in app.js as well as clientIndex.js which is unnecessary.
import { Route, Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';
const history = createMemoryHistory();
<Router history={history}>
<Route path="/" exact render={( props ) => ( <div>Helloworld</div> )} />
</Router>
You can now replace StaticRouter with ConnectedRouter which can be used both in client and server. I use the following code to choose between history and export it to be used in ConnectedRouter's history.
export default (url = '/') => {
// Create a history depending on the environment
const history = isServer
? createMemoryHistory({
initialEntries: [url]
})
: createBrowserHistory();
}
In clientIndex.js
Rather than BrowserRouter use StaticRouter.
import { BrowserRouter } from 'react-router-dom';
import { StaticRouter } from 'react-router-dom'
As is essentially noted in the comments, one may hit this error (as I have) by accidentally wrapping your App component in a <BrowserRouter>, when instead it is your client app that should be wrapped.
App.js
import React from 'react'
const App = () => <h1>Hello, World.</h1>
export default App
ClientApp.js
import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import ReactDOM from 'react-dom'
import App from './App'
const render = Component => {
ReactDOM.render(
<BrowserRouter>
<Component />
</BrowserRouter>,
document.getElementById('app')
)
}
render(App)
See also the React Router docs.
I'm trying to use React Router 4.2.2 in order to load a component called PostFocus whenever I click on a 'Card' component, with a Link wrapped around it. When I click on a 'Card' the path changes correctly, but the PostFocus component isn't rendered. Have I done something wrong or missed something out in the Route? I can't figure it out.
Here is the code:
class PostsList extends React.Component {
render() {
var createCards = this.props.posts.map((post, i) => {
return (
<div key={i}>
<Link to={`/${post.id}`}>
<Card title={post.title} subtitle={post.subtitle} date={post.date} id={post.id}/>
</Link>
<Route exact path={`/${post.id}`} render={(post) => (
<PostFocus content={post.content}/>
)}/>
</div>
);
});
return (
<div>
{createCards}
</div>
);
}
App Component:
import React from 'react';
import PostsList from '../containers/posts_list.js';
import {withRouter} from 'react-router';
class App extends React.Component {
render() {
return(
<div>
<PostsList />
</div>
);
}
}
export default withRouter(App);
index.js code:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxPromise from 'redux-promise';
import { BrowserRouter } from 'react-router-dom';
import App from './components/App.jsx';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
, document.getElementById('root'));
I was also facing the same problem. I fixed it with a trick.
You might have BrowseRouter in your App.js or index.js, I had it in my index.js like this :
ReactDOM.render(<BrowserRouter>
<App />
</BrowserRouter>, document.getElementById('root'))
I changed it to :-
ReactDOM.render((
<BrowserRouter>
<Route component={App} />
</BrowserRouter>
), document.getElementById('root'))
and it tricked, actually we are keeping the router look over our complete application by doing this, thus it also checks up with the routing path and automatically renders the view. I hope it helps.
Note:- Do not forget to import Route in your index.js
#Tom Karnaski
Hi... Sorry for the late reply, I was not getting time to work on it.. Your code is running in my system, I didn't had access to push a branch in your repo.. make your App.js like below.. it will work for sure..
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom'
import Navbar from './Components/Navbar/Navbar';
class App extends React.Component {
render() {
return (
<Router>
<div className="App">
<Route component={Navbar}/>
</div>
</Router>
);
}
}
export default App;
I solved this problem simply use tag instead of Link helper. Not sure is it right or not, but it works for me, hope it will helps anybody else.
I am trying to implement react router but having few problems. Please find the code below:
import React from 'react';
import ReactDOM from 'react-dom';
import { App, Home, Signup } from './containers';
import routes from './routes';
import { BrowserRouter , Route } from 'react-router-dom'
ReactDOM.render(
<BrowserRouter>
<App>
<Route path='/' component={Home} />
<Route path='/signup' component={Signup} />
</App>
</BrowserRouter>,
document.getElementById('app')
);
The App.js file which I am using as a Layout is as below:
import React, { Component } from 'react';
import { Cheader } from '../components';
class App extends Component {
render() {
return(
<div>
<Cheader/>
{this.props.children}
</div>
)
}
}
export default App;
It works when I navigate to http://localhost:3000/, but it does not work when i try to navigate to http://localhost:3000/signup. The page displays the following error:
Cannot GET /signup
The code for signup components and containers is as below:
components: index.js, signuppage.js
import Cheader from './cheader';
import Signuppage from './signuppage';
import Homepage from './homepage';
export {
Cheader,
Homepage,
Signuppage
}
import React from 'react';
import { Grid, Row, Col } from 'react-bootstrap';
const Signuppage = () => (
<Grid>
<Row>
<Col xs={12} sm={12} md={12}>
This is test
</Col>
</Row>
</Grid>
);
export default Signuppage;
containers: index.js, Signup.js
import App from './App';
import Home from './Home';
import Signup from './Signup';
export {
App,
Home,
Signup
}
import React, { Component } from 'react';
import { Signuppage } from '../components';
class Signup extends Component {
render () {
return (
<Signuppage/>
)
}
}
export default Signup;
It seems to be working for the default path, but not for any other route. am I missing any configuration here. Please note that I am using react-router v4. Can anyone please let me know.
Thanks
It is expalined in this: React-router urls don't work when refreshing or writting manually
When you try to go to the link directly, your server cannot find a file match to signup.
Solution 1: Use HashRouter to replace BrowserRouter.
Solution 2: Use fallback technique to setup server that fall back to '/' when no file matched is found.
you have to add exact to the first route
<App>
<Route exact path='/' component={Home} />
<Route path='/signup' component={Signup} />
</App>
another thing can be that you missing pushState settings in your dev server configuration
if you use webpack, add:
devServer: {
port: 3000,
historyApiFallback: true
}
I'm having an issue with react-redux Provider:
I moved our router out of our index.js to a routing.js file. I used a Provider to give my Routing component knowledge of the store but I'm getting a strange warning before the execution reaches the render method :
Warning: Failed context type: The context `store.isRequired` is marked as required in `Routing`, but its value is `undefined`.
This happens even if I get rid of the .isRequired in Routing.contextTypes. Moreover if I put a debugger statement at the beginning of the render function, it appears that this.contextisn't undefined and my app is working like a charm. I'm wondering if I did something wrong or if it could possibly be a bug of react-redux Provider or something.
Here is my code:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { setLanguage } from 'redux-i18n';
import I18n from 'redux-i18n/immutable';
import configureStore from './store/configure_store';
import { Routing } from './routing';
import translations from './translations';
import '../scss/index.scss';
const store = configureStore();
store.dispatch(setLanguage(navigator.language));
ReactDOM.render(
<Provider store={ store }>
<I18n translations={ translations }>
<Routing />
</I18n>
</Provider>,
document.getElementById("root")
);
routing.js (simplified for reading purpose)
import React from 'react';
import { Route, IndexRedirect, IndexRoute, Router, browserHistory } from 'react-router';
import AppContainer from './components/App/App';
import Base from './components/Root/Base';
import BaseInProject from './components/App/BaseInProject';
import { ProjectListContainer } from './components/App/Projects/ProjectsList';
export class Routing extends React.Component {
render() {
const { store } = this.context;
const beforeAppRouteEnter = (nextState, replace, callback) => {
// This function needs to store.dispatch some stuff
};
// Some other router functions
const routes = (
<Route path='/' component={ Base }>
<Route component={ AppContainer } onEnter={ beforeAppRouteEnter }>
<IndexRoute component={ ProjectListContainer } />
// Some other routes
<IndexRedirect to='media' />
</Route>
</Route>
</Route>
);
return (
<Router history={ browserHistory }>{ routes }</Router>
);
}
}
Routing.contextTypes = {
store: React.PropTypes.shape(React.PropTypes.any)
};
Thanks!