I've been trying to create a SPA on an electron project using React, React-Router and typescript (boostrapped from here).
I'm currently just trying to make it reroute to a different route via a <Link> but I'm getting an error in the console saying
Uncaught DOMException: Failed to execute 'pushState' on 'History': A history state object with URL 'http://settings/' cannot be created in a document with origin 'http://localhost:2003' and URL 'http://localhost:2003/'.
where localhost:2003 is the port associated with the project. I'm not sure how I can fix this as I believe this is a problem specific with electron? Not sure..
The code I'm running is exactly the same as https://codesandbox.io/s/weathered-river-9yrbv
(please to go /app first in the sandbox)
You mad mistake to load props in App function.
function App(props) {
console.log(props);
return (
<div className="App">
{/* {props} // Remove this line... */}
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<ProtectedRoute path="/app" component={MainComponent} />
</div>
);
}
You have to wrap App component via Route.
import { BrowserRouter as Router, Link, Route } from "react-router-dom";
...
...
render(
<Router>
<Route path="/" component={App}/>
</Router>,
rootElement
);
Now you can get the props in console.log.
Here is the updated working code for you.
https://codesandbox.io/s/elegant-elion-qr1qf
Hope this will work for you!
Related
So I am currently doing a Web Dev boot camp, and we are busy with a project where we make an API for an application where you can browse movies, select your favourite, make a profile etc.
The current task, has us implementing React Routers to the endpoints.
I followed the code as per the exercise but my app would only show my navbar and background colour. I went into the dev tools, and got this error.
utils.ts:767 Matched leaf route at location "/register" does not have an element. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.
OR
Matched leaf route at location "/" does not have an element. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.
I looked online for answers, but every answer refers to changing "component" to "element". The problem is, the code that we were taught, doesn't even have that included.
Just some of the code:
render() {
const { movies, user, favouriteMovies } = this.state;
console.log(favouriteMovies);
return (
<Router>
<NavBar user={user} />
<Row className="main-view justify-content-md-center">
<Routes>
<Route
exact
path="/"
render={() => {
/* If there is no user, the LoginView is rendered. If there is a user logged in,
the user details are passed as a prop to the LoginView */
if (!user)
return (
<Col>
<LoginView
movies={movies}
onLoggedIn={(user) => this.onLoggedIn(user)}
/>
</Col>
);
// Before the movies have been loaded
if (movies.length === 0) return <div className="main-view" />;
return movies.map((m) => (
<Col md={6} lg={3} key={m._id} className="movie-card">
<MovieCard movie={m} />
</Col>
));
}}
/>
<Route
path="/register"
render={() => {
if (user) return <Redirect to="/" />;
return (
<Col>
<RegistrationView />
</Col>
);
}}
/>
I then asked on Slack where the other students chat. There was someone with the same issue and they said they installed an older version and it worked.
npm install react-router-dom#5.3.0
I did that, but now my navbar doesn't show, only the background colour.
I also have a different error.
react-dom.development.js:86 Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot
printWarning # react-dom.development.js:86
main-view.jsx:125 Array(0)
react-jsx-runtime.development.js:87 Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `MainView`.
at MainView (http://localhost:1234/index.6701a6e1.js:25282:9)
at MyFlixApplication (http://localhost:1234/index.6701a6e1.js:955:1)
printWarning # react-jsx-runtime.development.js:87
react-dom.development.js:28439 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `MainView`.
at createFiberFromTypeAndProps (react-dom.development.js:28439:17)
at createFiberFromElement (react-dom.development.js:28465:15)
at reconcileSingleElement (react-dom.development.js:15750:23)
at reconcileChildFibers (react-dom.development.js:15808:35)
at reconcileChildren (react-dom.development.js:19167:28)
at updateHostComponent (react-dom.development.js:19924:3)
at beginWork (react-dom.development.js:21618:14)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:14)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16)
at invokeGuardedCallback (react-dom.development.js:4277:31)
react-dom.development.js:18687 The above error occurred in the <div> component:
at div
at http://localhost:1234/index.6701a6e1.js:43098:48
at Router2 (http://localhost:1234/index.6701a6e1.js:29157:34)
at BrowserRouter2 (http://localhost:1234/index.6701a6e1.js:28837:39)
at MainView (http://localhost:1234/index.6701a6e1.js:25282:9)
at MyFlixApplication (http://localhost:1234/index.6701a6e1.js:955:1)
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
My tutor isn't able to find what the problem is.
I have really been struggling with this and would really appreciate any assistance.
The link to my repo:
https://github.com/Claudiaj501/myFlix-client/tree/Router
React Router v6 makes heavy use of React hooks, so you'll need to be on React 16.8+. The React Router Docs and Upgrade Guide will show you the differences between the two. Changing "component" to "element" is one of the several differences between the two versions. Here are the docs for the version 5 of React Router.
In your warning it tell you "ReactDOM.render is no longer supported in React 18". You should be using React functional components and not classes with the latest version of react.
In order to use v6, you'll need to convert all your Switch elements to Routes. So if you downgraded from 6 to 5, you can't use Routes.
Here is a v5 example:
<BrowserRouter>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/users">
<Users />
</Route>
</Switch>
</BrowserRouter>
And here is the same example in v6:
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="users/*" element={<Users />} />
</Routes>
</BrowserRouter>
You need to decide what version of everything you are using and stick to that. Several packages have major differences between versions. And you need to make sure that the version you are using of package X is compatible with React version Y.
I am using react router with my application and everything works fine locally. Below is my code. The issue is when I host it online it is in a my-application subdirectory:
https://www.example.com/my-application
This is breaking the code and it is not functioning as it should.
can anyone advise how to fix this issue? If there is anything unclear please feel free to ask. I have tried countless approaches but cannot get it to work. One answer can be seen here.
the issue I am getting is that with the current code it navigates to https://www.example.com/test as opposed to https://www.example.com/my-application/test. I thought if I hardcoded in the url it would work but this also breaks the application.
The code below is slightly whittled down to remove superfluous code.
import React, { Component } from 'react';
import styled from 'styled-components'
import { Route, Switch } from 'react-router-dom'
const Home = ({ avatarUrl }) => {
return (
<div>
<Route exact path="/" component={Overview}/>
<Route path="/test" component={Test}/>
</div>
);
};
class App extends Component {
render() {
return (
<section>
<Nav avatarUrl={ this.props.avatarUrl }/>
<Switch>
<Route path="/example" component={Example}/>
<Route path="/" render={()=><Home
avatarUrl={ avatarUrl }
/>}/>
</Switch>
</section>
)
}
}
export default App
Apply config changes pacakage.json add homepage page as your folder name
To solve this I just did two things:
Added "hostname": "https://www.example.com/my-application" at the top of package.json.
Added basename="my-application" to the BrowserRouter e.g. <BrowserRouter basename="my-application">
Note: I created the project using create-react-app. I am using react version 18 and react-router version 6.
I have this code:
<BrowserRouter>
<Route path="/(:filter)?" component={App} />
</BrowserRouter>
the filter param or '' on the root is suppose to be on App components' props base on the previous react router versions?
This is my code on my App:
const App = ({params}) => {
return ( // destructure params on props
<div>
<AddTodo />
<VisibleTodoList
filter={params.filter || 'all'} // i want to git filter param or assign 'all' on root
/>
<Footer />
</div>
);
}
I logged this.props.match.params on console but it has none? help?
I assume you are following the Redux tutorial on Egghead.io, as your example code seems to use what is defined in that video series. I also got stuck on this part trying to integrate React Router v4, but eventually found a working solution not far from what you have tried.
⚠️ NOTE: one thing I would check here is that you are using the
current version of react-router-dom (4.1.1 at the time of this
writing). I had some issues with optional filters in the params on
some of the alpha and beta versions of v4.
First, some of the answers here are incorrect, and you indeed can use optional params in React Router v4 without the need for regular expressions, multiple paths, archaic syntax, or using the <Switch> component.
<BrowserRouter>
<Route path="/:filter?" component={App} />
</BrowserRouter>
Second, as others have noted, React Router v4 no longer exposes params on route handler components, but instead gives us a match prop to use.
const App = ({ match }) => {
return (
<div>
<AddTodo />
<VisibleTodoList filter={match.params.filter || 'all'} />
<Footer />
</div>
)
}
From here, there are two ways to keep your content in sync with the current route: using mapStateToProps or using the HoC withRouter, both solutions are already talked about in the Egghead series so I won't recapitulate them here.
If you are still having trouble, I urge you to check out my repository of the completed application from that series.
Here is the commit using the mapStateToProps solution
Here is the commit using the withRouter soluiton
Both of which seem to work fine (I just tested both of them).
React Router v4 does not accept a regex for the path. You won't find regular expressions covered anywhere in the documentation. Instead of a regex you can just create multiple routes inside the <Switch> component and the first one that matches will be rendered:
<BrowserRouter>
<Switch>
<Route path="/" component={App} />
<Route path="/:filter" component={App} />
</Switch>
</BrowserRouter>
You also have a bug in your App component. You get the params via the match property, not the params property (not tested, but this should be closer to what you want):
const App = ({match}) => {
return (
<div>
<AddTodo />
<VisibleTodoList
filter={match.params.filter || 'all'}
/>
<Footer />
</div>
);
}
All of the above is covered in the React Router V4 docs on ambiguous matches
From the react-router documentation, props.match.params is where your parameteres are stored.
So to access the filter name, try this
const App = ({match}) => {
...
<VisibleTodoList
filter={match.params.filter || 'all'}
/>
...
}
I know the question is about v4, but if sm looks for v5, we can use the useParams hook.
// /:filter
const {filter} = useParams();
To get the params in the path URL
//to your route component
<Route path={`${match.url}/upload/:title`} component={FileUpload}/>
=====
//Parent component
<Link to={`${match.url}/upload/css`}>
=====
//Child component
const {params: {title}} = this.props.match;
console.log(title);
result = css
I do not know why react router cannot detect my filter even though it's working properly, I resolved this problem by using location.pathname since it does the work for me. I think react router cannot detect my filter param because of regexp, I expected that so I put || to use all on root, but unfortunately for me I it cannot detect so I used location.pathname . I would appreciate suggestions on this since I am not sure with my path configuration on regexp.
I have an issue using nested routes with react-router.
Here is my code (two simple react components, routes file to access comp1/comp2) :
House.js
export default connect(st => st)(class House extends React.Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
})
Window.js
export default connect(st => st)(class Window extends React.Component {
render() {
return (
<div >
hey hey
</div>
);
}
})
routes.js
export const routes = (
<Router history={ history }>
<Route path="/house" component={House}>
<Route path="/house/window" component={Window} />
</Route>
</Router>
);
When I redirect to "/house/window" programmatically, I can access the route and the page shows "hey hey".
If I want to access the url directly :
localhost:8080/house/window
It shows a blank page and a console error :
Request URL:http://localhost:8080/house/window
Request Method:GET
Status Code:304 Not Modified
And then :
GET http:// localhost:8080 /house/js/bundle.js (404)
Also, http:// localhost:8080 /house/ (with trailing slash) shows the same error.
I really don't understand this weird redirection http:// localhost:8080 /house/js/bundle.js
I'm probably doing something wrong, but after crawling stackoverflow, I still can't see it.
I found the issue : my bundle.js script included in index.html was included with a relative path 'js/bundle.js' so I changed it for '/js/bundle.js'.
Sadly, it didn't make any problem until I wanted to nest some routes.
Nested routes cannot have parent path included in path attribute:
export const routes = (
<Router history={ history }>
<Route path="/house/" component={House}>
<Route path="window" component={Window} />
</Route>
</Router>
);
I have this simple code that doesn't work. I took it from the react-router project page and modified slightly for it to look a bit better.
Setup
I have several very simple react components:
var IndexPage = React.createClass({
render(){
return (<h1>Index Page</h1>);
}
});
var AboutPage = React.createClass({
render(){
return (<h1>About page</h1>);
}
});
var NotFoundPage = React.createClass({
render(){
return (<h1>Not found page</h1>);
}
});
Also I have made a setup of react router:
var ReactRouter = require('react-router');
var Router = ReactRouter.Router;
var Route = ReactRouter.Route;
var BrowserHistory = ReactRouter.browserHistory;
var Render = ReactDOM.render;
And that's how I use react router 2.0.
Render((
<Router history={BrowserHistory}>
<Route path="/" component={IndexPage}>
<Route path="about" component={AboutPage}/>
<Route path="*" component={NotFoundPage}/>
</Route>
</Router>
), document.body)
I use BrowserHistory (not HashHistory) to avoid hash in urls.
My server is raised under IIS 10 (Windows 10) on 8080 port.
Problem
http://localhost:8080/
goes to IndexPage component. This is correct.
http://localhost:8080/about
goes to IIS 404 error page. Routing doesn't work in this case
http://localhost:8080/ttt
goes to IIS 404 error page again.
So the router doesn't see this nested paths that go after /. And it doesn't even care about whether they are correct or not.
What can cause such a strange behavior?
Thanks in advance!
Update
I've found out that the next string solves the problem with a client routing:
{this.props.children}
This is the fixed code:
var IndexPage = React.createClass({
render(){
console.log('index page render');
return (<div>
<h1>Index Page</h1>
<Link to={ '/about' }>about</Link>
{this.props.children}
</div>);
}
});
Is your server configured to map all application-paths to your index.html? You should never get a IIS 404 if your server would map all path to your index file, as it always would deliver this one.
React-router is a client-side routing solution(also works in server side, but it seems you are using .Net as the server side handler).
You can try this(Link from React-Router):
<Link to={ pathname: 'about' }>
about
</Link>
Put it in the index page's component, and click the link, the react-router will work.
Update:
{this.props.children} ref to the inner component(AboutPage, NotFoundPage).
If you change code to that:
<Route path="/" component={IndexPage} />
<Route path="/about" component={AboutPage}/>
<Route path="*" component={NotFoundPage}/>
It will works.(remove the {this.props.children} in IndexPage if there is no nesting routes).
I was able to solve my issue linking directly to URLs by adding --history-api-fallback to my webpack-dev-server command.
Setting this flag prompts webpack-dev-server to serve the index page instead of 404. The index page will then route correctly on the client side.