I setup simple route within my index.js file.
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import reduxThunk from 'redux-thunk';
import '../less/app.less';
import reducers from './reducers';
import App from './components/App';
import Login from './components/auth/Login';
import Welcome from './components/Welcome';
// const defaultSetting = settings;
const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Welcome} />
<Route path="login" component={Login} />
</Route>
</Router>
</Provider>
, document.querySelector('.container')
);
my App.js
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
export default App;
When I navigate to localhost:8080 using webpack-dev-server I can properly show my index route. but when I navigate to localhost:8080/login' it shows errorCannot GET /login`.
Any solution?
By default the server will look for an html file at the /login route. So you should configure it for html5 navigation to return you index.html for any route it receives.
EDIT:
To do so in webpack, as you suggest in the comments, you can add this to your webpack dev server config:
historyApiFallback: true
index.html should be the default, so no need to specify it.
Also please note that urls containing dots are still pointing to files and thus redirected to the server. For example, if you have an url such as /search/firsname.lastname you would need to add a handler for this.
historyApiFallback: {
rewrites: [
{
from: /^\/search\/.*$/,
to: function() {
return 'index.html';
}
}
]
},
See this issue for more info.
Related
i am trying to make a navigaton on my website by react-router and typescript. but its not working and instead of Home page i get an empty page
Thats my app.tsx file
// app.tsx
import * as React from 'react';
import '../App.css';
class App extends React.Component<any,any> {
public render() {
return (
<div>
{this.props.children}
</div>
);
}
}
export default App;
index.tsx
// index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
import {AppRouter} from './router';
ReactDOM.render(
<AppRouter/>,
document.getElementById('root') as HTMLElement
);
registerServiceWorker();
router.tsx
import * as React from 'react';
import { Route,Router } from 'react-router';
import App from './components/App';
import HomePage from './components/home/HomePage';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
export const AppRouter = () => {
return (
<Router history={history}>
<Route path="/" component={App} >
<Route path="/" exact={true} component={HomePage} />
</Route>
</Router>
);
}
i dont really dont know what to say. i cant find any possible info about this. If u know better way to make navigation with typescript, react and redux i am open for ideas. thx
In the App component, you are doing {this.props.children}. So you should not pass that component to any route.
You need to add all the routes as a child of that component through which you will get the children in your props.
Also, for switching between routes, you should bind all the routes in the 'Switch' imported from react-router.
So, your router.tsx file should look like:
import * as React from 'react';
import { Route, Router, Switch } from 'react-router';
import App from './components/App';
import OtherComponent from './components/OtherComponent';
import HomePage from './components/home/HomePage';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
export const AppRouter = () => {
return (
<App>
<Router history={history}>
<Switch>
<Route exact={true} component={HomePage} />
<Route path="/other" component={OtherComponent} />
</Switch>
</Router>
</App>
);
}
By this, you will get the 'HomePage' component at route '/' and OtherComponent at route '/other'.
Previously, I was able to reroute user (e.g. on successful login) using browser history:
import { browserHistory } from 'react-router'
browserHistory.replace('/home')
In the new react-router I am no longer able to import browserHistory, what is the alternative way to achieve my goal?
import { Router, Route } from 'react-router'
import { createBrowserHistory } from 'history'
export default () => (
<Router history={createBrowserHistory()} >
<Route exact path="/" component={MainPageComponent} />
</Router>
)
In MainPageComponent you can use this.props.history.push('/home').
Learn about router history here https://github.com/ReactTraining/history
I try to use react-router-dom 4.0.0 library. But it send me this error
Uncaught TypeError: Cannot read property 'location' of undefined
It seems that problem in browserHistore. Before I used react-router 2.x.x and everything was alright.
This is my index.js
import 'babel-polyfill'
import React from 'react'
import { Router, hashHistory } from 'react-router-dom'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { configureStore } from './store'
import { routes } from './routes'
const store = configureStore()
render(
<Provider store={store}>
<Router history={hashHistory} routes={routes} />
</Provider>,
document.getElementById('root')
)
This is my routes
import React from 'react'
import { IndexRoute, Route } from 'react-router-dom'
import App from './containers/App'
import Main from './containers/Main'
import First from './containers/First'
export const routes = (
<Route path='/' component={Main}>
<Route path='/path' component={First} />
<IndexRoute component={App} />
</Route>
)
And also for server side express I set this get configuration
app.get('*', function root(req, res) {
res.sendFile(__dirname + '/index.html');
});
React Router v4 is a complete re-write and isn't compatible with previous versions as you're assuming in your code. With that said, you shouldn't expect to be able to just upgrade to a new major version (V4) and have your app work as normal. You should check out the documentation or downgrade back to V2/3. Here's some code that should get you started in the right direction
import 'babel-polyfill'
import React from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { configureStore } from './store'
import App from './containers/App'
import Main from './containers/Main'
import First from './containers/First'
const store = configureStore()
render(
<Provider store={store}>
<Router>
<Route path='/' component={Main} />
<Route path='/path' component={First} />
</Router>
</Provider>,
document.getElementById('root')
)
Check the version of react-router-dom in package.json
If its version is greater than 4 then in your file import BrowserRouter :-
import { BrowserRouter as Router, Route } from 'react-router-dom'
else if its version is less than 4 then import Router :-
import { Router, Route } from 'react-router-dom'
Install npm history package: npm i history
and then use it as follow in your index/routes file:
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Switch, Route} from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
import App from './components/App';
import './index.css'
const history = createBrowserHistory();
ReactDOM.render(
<Router history={history}>
<Switch>
<Route path='/' component={App}/>
</Switch>
</Router>,
document.getElementById('root')
);
I have basically copied code straight from the documentation, and it is throwing a peculiar error.
Warning: Failed prop type: The prop `history` is marked as required in
`Router`, but its value is `undefined`.
in Router
Here is my code:
client/main.jsx
import React from "react"
import { render } from "react-dom"
import { Meteor } from "meteor/meteor"
import { renderRoutes } from "../imports/ui/Routes.jsx"
Meteor.startup(() => {
render(renderRoutes(), document.getElementById('react-root'))
})
imports/ui/Routes.jsx
import React from 'react'
import { render } from "react-dom"
import { Router, Route, IndexRoute, browserHistory } from 'react-router'
// route components
import App from "./App.jsx"
export const renderRoutes = () => (
<Router history={browserHistory}>
<Route path="/" component={App} />
</Router>
)
imports/ui/App.jsx
import React, { Component } from 'react'
import TopBar from "./components/TopBar.jsx"
import LeftMenuContainer from "./components/LeftMenuContainer.jsx"
import LivePurchases from "./components/LivePurchases.jsx"
// App component - represents the whole app
export default class App extends Component {
render() {
return (
<div className="App">
<div className="flexWrapperGlobal">
<TopBar/>
<div className="contentContainer">
<LeftMenuContainer/>
<div className="bodyContainer">
<LivePurchases/>
<div className="siteContentContainer">
{this.props.children || "test"}
</div>
</div>
</div>
</div>
</div>
)
}
}
It appears that it should not be giving this error, as I am setting the prop at history={browserHistory}
Switch over to the example from the React Docs,
imports/ui/Routes.jsx
import React from 'react'
import { render } from "react-dom"
import { Router, Route, IndexRoute } from 'react-router'
import createBrowserHistory from 'history/createBrowserHistory'
// route components
import App from "./App.jsx"
const history = createBrowserHistory()
export const renderRoutes = () => (
<Router history={history}>
<Route path="/" component={App} />
</Router>
)
I have 3 apps with this structure:
import React from 'react'
export default React.createClass({
render() {
return <div>Hey App1!</div>
}
})
import React from 'react'
export default React.createClass({
render() {
return <div>Hey App2!</div>
}
})
import React from 'react'
export default React.createClass({
render() {
return <div>Hey App3!</div>
}
})
And in my main.js:
import React from 'react'
import ReactDOM from 'react-dom'
import {Router, Route, browserHistory, IndexRoute } from 'react-router'
import App1 from './modules/App1.js'
import App2 from './modules/App2.js'
import App3 from './modules/App3.js'
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/" component={App1}>
<IndexRoute component={App1} />
<Route path="app1" component={App2} />
<Route path="app2" component={App3} />
</Route>
</Router>
), document.getElementById('app'))
But when I try /#/app1 or /#/app2 addresses in my browser it shows the / result (it means 'Hey App1").
My Reactjs version is: 15.3.2
your preferred history is browserHistory. Then the URLs should look like example.com/some/path.
So try /app1 or /app2 without hash in the url.
Hash history uses the hash (#) portion of the URL, creating routes that look like example.com/#/some/path.
If you want to use hash in the url pass hashHistory as props instead of browserHistory