React router history not render correctly - javascript

I'm using https://github.com/newtriks/generator-react-webpack to create an APP.
Everything is cool, I generate my dist files, but I upload my app on my website, like this: my-website.com/staging/my-app.
But when I navigate to my-website.com/staging/my-app it renders the error component, and If I press Home button, I see the homepage as excepted but the url in the navbar is my-website.com/.

If your website doesn't located in the root url, you will need to provide a basename option
For example:
import createBrowserHistory from "history/lib/createBrowserHistory"
import { Router, useRouterHistory } from "react-router"
const browserHistory = useRouterHistory(createBrowserHistory)({
basename: "staging/my-app",
})
// component
<Router history={ browserHistory } routes={ routes } />

Related

Why on react history createHashHistory appends /# for each path?

I have an application with this config for history:
import { createHashHistory } from 'history';
import { ConnectedRouter } from 'connected-react-router';
const history = createHashHistory({
hashType: 'slash',
});
...
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
But all my routes get appended by /#
ex: localhost:8080/ becomes: localhost:8080/#/
I already tried to update my packages as this question say but it didn't work.
The only thing that worked was change createHashHistory to createBrowserHistory, but I'm not sure what's the difference between them, and why createHashHistory is appending the /#
With hashHistory, it produces url like
http://yourwebsite.net/#page/xxx
With browserHistory, it produces url like
http://yourwebsite.net/page/xxx
Which one to use? In real-world products, browserHistory is mostly used. A rule of thumb is "if you are using a dynamic server that can handle dynamic URLs then you need to use the BrowserRouter component but if you are using a server that only serves static files then a HashRouter component is what to be used in this case."
In your code, hashType: 'slash' is just the default value.

Is Fetching Data in App.js file allowed in React App?

I have built authorization into my React App using passport.js, and I would like to, in my App.js file, fetch my authorization routes to see if a user is logged into the app, or if nobody is logged in.
To help with the question, I have shared a condensed version of my React App's App.js file, and Index.js file.
// App.js File
// Import React Libraries, Routes, Container Pages
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Route } from 'react-router-dom';
import { userActions } from './actions/auth/auth-actions.js';
import GameLanding from './containers/StatsPages/Game/GameLanding';
import AppFooter from './components/AppFooter';
// And Create The App
class App extends Component {
constructor(props, context) {
super(props, context);
}
componentDidMount() {
this.props.dispatch(userActions.authorize());
}
render() {
return (
<div>
<Route exact path='/stats/games' render={() => <GameLanding userInfo={this.props.userInfo} />} />
<AppFooter />
</div>
);
}
}
// export default App;
function mapStateToProps(reduxState) {
return {
userInfo: reduxState.authorizedReducer.userInfo,
authorized: reduxState.authorizedReducer.authorized,
loading: reduxState.authorizedReducer.loading
};
}
export default connect(mapStateToProps)(App);
... my entire App.js file has ~15 Routes components, and (part of) my goal with my App.js file is to fetch the authorized and userInfo props, and pass these to the components in the various routes. I showed an example where I pass the userInfo prop to the GameLanding component.
Here is how I have set up my Index.js file.
// Index.js
// Import Libraries
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
// Import CSS and the App
import App from './App';
import 'react-table/react-table.css';
import './index.css';
import './App.css';
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
document.getElementById('root'));
My current problem is as such: For some reason, fetching the userInfo and authorized props is breaking my app. I am unfortunately getting no error messages... rather, all of the react-router-dom Links in my app are simply not working... clicking them changes the url, but the pages of my app no longer change...
My questions are then, (a) am i allowed to fetch authorization data in App.js in the manner I am doing so (using connect, with mapStateToProps, etc.), or am I doing this all wrong?
Whether or not somebody is logged into my app is an app-wide thing, not a page-specific thing, and I figured for this reason (also to prevent having to fetch auth props in many many container pages) that App.js is the best place to grab these props.
Any thoughts on why my app is breaking, or how else my App.js file should look (I am ~99% sure my index.js is fine), would be greatly appreciated! Thanks!
Edit: For reference, doing the following: (i) importing userActions, (ii) calling userActions.authorize() in componentDidMount, (iii) including the mapStateToProps and connect on bottom of app, etc. works for loading the auth props in any of my container components. e.g. if i had this code in my GameLanding component, it doesnt break the react-router-dom Links app-wide in the same manner that it does when this code is in App.js. Hence the title of the question. Thanks!
1) Reason for app breaking:
I am assuming userInfo and authorized props will be undefined, as component renders initially before componentDidMount runs and you have not handled undefined props. You could also pass default props for these props.
2) Better structure for authorization
I am assuming you need to authenticate each route for authorization.
i) Create routes file and enter all routes for your app.
ii) <Route exact path='/stats/games' component={GameLanding} onEnter={reqAuth}/>
Inside reqAuth function you should check if the user is authorized for that route or not.
iii) Inside App component call action for fetching data, store in store and use GameLanding as child component and pass props only when they are defined.
That is not whole code, but should give you gist.
Happy Coding!!!

react router won't serve me components other paths than '/'

Hi i added react router to my project but it wont serve me path others than '/'
import React from 'react';
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import store from './reducers'
import Header from './header/header'
import Toolbar from './toolbar/toolbar'
import Createprocess from './createprocess/createprocess'
import Hider from './createprocess/hider'
ReactDOM.render(<Provider store={store}>
<Router>
<Route path='/module' component={Createprocess} />
</Router>
</Provider>,
document.getElementById('root')
)
ReactDOM.render(<Header/>,document.getElementById('header'))
ReactDOM.render(<Toolbar/>,document.getElementById('tools-bar'))
this my createprocess component code :
import React, {Component} from 'react'
import Actionsbar from './actionsbar'
import Processdisp from './processdisplay'
import DefineTask from './taskdefinition'
import store from '../reducers'
export default class Createprocess extends Component{
render(){
return (<div id='create-process' className='default app-container'>
<Actionsbar/>
<Processdisp data={store.getState().processState}/>
<DefineTask/>
</div>)
}
}
when i add the module path i can't get it from my browser even if i used many combination
but the only time react renders is when i use th '/' path and i call my html page on the browser
i'm web designer i started webdevelopping recently and it seem that i can't get my head around those paths and serving pages, help please (i'm using babel/webpack).
Wrap the route in a Switch component from react router
I found the solution, it seems that because there is no server serving pages i should have user HashRouter istead of BrowserRouter

React-Router Nested Routes not working

Steps to reproduce
client.js (entry file)
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { Router, browserHistory } from 'react-router';
import reduxThunk from 'redux-thunk';
import reducers from './reducers';
import routes from './routes.js';
const storeWithMiddleware = applyMiddleware(reduxThunk)(createStore);
const store = storeWithMiddleware(reducers);
ReactDOM.render(
<Provider store={store}>
<Router history={browserHistory} routes={routes} />
</Provider>, document.getElementById('app')
);
routes.js (ver 1)
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import App from './components/bases/app.js';
import Login from './components/app/authentication/login.js';
export default(
<Route path="/" component={App}>
<Route path="signup" component={Login}/>
</Route>
)
routes.js (ver 2)
let routes = {
path: '/',
component: App,
childRoutes: [
{ path: 'signup', component: Login }
]
}
export default routes;
Expected Behavior
Expect to have /signup route avail.
Actual Behavior
react-router cannot find the route /signup but can find /
Having a look at the chrome dev-tools source-tab, this is what I find:
When looking at "/"
sources
--------
dist/prod
| bundle.js
index.html
When looking at "/signup"
sources
--------
signup
If you changed to hashHistory and it worked it probably be your backend which serves the html...
Since hashHistory works like this:
example.com/#/signup
The browser doesn't understand as a new GET, if you use browseHistory, this:
example.com/signup
Makes the browser request for index.html again but on path /signup ... but the webpack dev server probably don't understand..
Try adding historyApiFallback: true to webpack config
LIke this
https://github.com/amacneil/react-router-webpack-history-example
The giveaway is the files that are being served when you are looking at the sources. When you are trying to load the /signup page, your browser is trying to load a signup page.
When you use browserHistory, you need to serve your index.html (and any scripts included in it) for all possible routes. This means that you need to have a server which accepts all possible routes and responds accordingly.
For example, if you are running a node server using express, you would need to have a wildcard route handler:
// define static handler first for .js, etc.
app.use(express.static(path.join(__dirname, 'public')));
// all other routes should server your index.html file
app.get("/", handleRender);
app.get("*", handleRender);
function handleRender(req, res){
res.sendFile(__dirname + '/index.html');
}

How can I navigate outside of components in react-router-1.0.3 in React's render()?

I want to route to another path in the render function in react-router-1.0.3. I can redirect the user by providing a link using:
render(
<Link to={`/${this.props.params.projectSlug}/`}>
Please follow this link to access your workspace.
</Link>
)
But I cant seem to programmatically forward to this link. I tried:
render(
<Router history={browserHistory} routes=
{`/${this.props.params.projectSlug}/`}/>
)
How can I programmatically forward to a relative path in react-router 1.0.3?
Try upgrade router to the latest version if you don't mind;
Then, they strictly clarify how to do it here.
// Your main file that renders a <Router>:
import { Router, browserHistory } from 'react-router'
import routes from './app/routes'
render(
<Router history={browserHistory} routes={routes} />,
mountNode
)
&
// Somewhere like a Redux middleware or Flux action:
import { browserHistory } from 'react-router'
// Go to /some/path.
browserHistory.push('/some/path')
// Go back to previous location.
browserHistory.goBack()

Categories