react-router-redux: Module build failed: SyntaxError: Unexpected token ...reducers - react-router

//app.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import createHistory from 'history/createBrowserHistory';
import { Route } from 'react-router';
import { ConnectedRouter, routerReducer, routerMiddleware, push } from 'react-router-redux';
import App from './components/app.js';
import reducers from './reducers';
const history = createHistory();
const middleware = routerMiddleware(history);
// Add the reducer to your store on the `router` key
// Also apply our middleware for navigating
const store = createStore({
...reducers,
router: routerReducer
},
applyMiddleware(middleware)
);
const About = () => {
return (<div>
Will this work?
</div>);
}
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<Route exact path="/" component={App}/>
<Route path="/about" component={About}/>
</div>
</ConnectedRouter>
</Provider>
, document.querySelector('#app'));
Here is my reducers/index.js code.
//reducers/index.js
import { combineReducers } from 'redux';
import { mobileLinks } from './reducer_header';
import UserDetailsReducer from './reducer_user_details';
const rootReducer = combineReducers({
mobileLinks,
userDetails: UserDetailsReducer
});
export default rootReducer;
What do I do to fix this? I'm unable to find any examples for the new version of react-router-redux. I've tried moving the routerReducer to reducers/index.js but that didn't work either. Can someone please help?

Most likely you do not have Babel set to transpile the Object Spread Operator, you can read up on it here.
You can simply install the Babel "Object rest spread transform" preset like so:
npm install --save-dev babel-plugin-transform-object-rest-spread
And add it to your list of plugins:
{
"plugins": [
// Other plugins...
"transform-object-rest-spread"
]
}

Related

Uncaught Error: useRoutes() may be used only in the context of a <Router> component [duplicate]

I have installed react-router-domV6-beta. By following the example from a website I am able to use the new option useRoutes I have setup page routes and returning them in the App.js file.
After saving I am getting the following error:
Error: useRoutes() may be used only in the context of a component.
I am wondering If I am missing something here? I have created the pages inside the src/pages folder.
My code:
import { BrowserRouter, Link, Outlet, useRoutes } from 'react-router-dom';
// Pages
import Home from './pages/Home';
import About from './pages/About';
import Services from './pages/Services';
import Gallery from './pages/Gallery';
import Prices from './pages/Prices';
import Contact from './pages/Contact';
const App = () => {
const routes = useRoutes([
{ path: '/', element: <Home /> },
{ path: 'o-nama', element: <About /> },
{ path: 'usluge', element: <Services /> },
{ path: 'galerija', element: <Gallery /> },
{ path: 'cjenovnik', element: <Prices /> },
{ path: 'kontakt', element: <Contact /> }
]);
return routes;
};
export default App;
You should have a <BrowserRouter> (or any of the provided routers) higher up in the tree. The reason for this is that the <BrowserRouter> provides a history context which is needed at the time the routes are created using useRoutes(). Note that higher up means that it can't be in the <App> itself, but at least in the component that renders it.
Here's what your entry point could look like:
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root'),
);
I think the problem is that you still need to wrap routes (Routes / useRoutes) inside a Router element.
So an example would look something like this:
import React from "react";
import {
BrowserRouter as Router,
Routes,
Route,
useRoutes,
} from "react-router-dom";
const Component1 = () => {
return <h1>Component 1</h1>;
};
const Component2 = () => {
return <h1>Component 2</h1>;
};
const App = () => {
let routes = useRoutes([
{ path: "/", element: <Component1 /> },
{ path: "component2", element: <Component2 /> },
// ...
]);
return routes;
};
const AppWrapper = () => {
return (
<Router>
<App />
</Router>
);
};
export default AppWrapper;
Refactor according to your needs.
its means in Your index js Or App JS wrap with BrowserRouter like this
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<BrowserRouter> // Like This here I am using
<App />
</BrowserRouter>
</Provider>
</React.StrictMode>,
document.getElementById("root"),
);
Mention below code in index.js
import { BrowserRouter as Router } from "react-router-dom";
Just want to report on a similar issue -- as of writing (v6.2.1), it seems you actually encounter this error as well if you are importing from react-router instead of react-router-dom. A costly typo on my part.
I.e., make sure you are importing Routes and Route from react-router-dom and NOT react-router
// This is deceptively valid as the components exist, but is not the intended usage
import { Routes, Route } from 'react-router';
// This works and is the intended usage
import { Routes, Route } from 'react-router-dom';
Code: index.js
import {BrowserRouter as Router} from "react-router-dom";
ReactDOM.render(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>,
document.getElementById("root")
);
app.js
function App() {
return (
<>
<Routes>
<Route path ="/" element={<Main />} />
<Route path ="gigs" element={<Gigs />} />
</Routes>
</>
);
}
Try to add your routes in index.js not in App.js. Your App.js is called from index.js. In the index.js your external page is called like this
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<Navbar />} />
</Routes>
</BrowserRouter>
</React.StrictMode>
);
> Following codes works since react-router-dom syntax changed because of React 18.
import logo from './logo.svg';
import './App.css';
import Header from './components/Header';
import Login from './components/Login';
import {
BrowserRouter as Router,
Routes,
Route,
useRoutes,
} from 'react-router-dom';
import Signup from './components/Signup';
function AppRoutes() {
const routes = useRoutes(
[
{path:'/',element:<Login/>},
{path:'/signup',element:<Signup/>}
]
)
return routes;
}
function App(){
return (
<Router>
<Header/>
<AppRoutes />
</Router>
)
}
export default App;
Try
const Routes = () => useRoutes([])
and then wrap it like this in App.js
<BrowserRouter>
<Routes />
</BrowserRouter>
It worked for me
I got this error because I had two different versions of react-router-dom being bundled.
If you're using npm/yarn workspaces, check that there is only one installed version of react-router-dom in the top-level node_modules folder

React-router-dom params undefined in nested route after using link

I need a switch component to have access to route params. The switch is rendered in one of the routes but its also rendered outside of it. Is there a way to get the same params in the component rendered outside of the route? Thanks for the help in advance!
It's usually a good pattern to not directly pass params through the route and keep those simple with the view component. You can use useContext, and then have each component(route) plug into that state using the useContext hook in the component.
for example...
app.js
import { useState } from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { Routes } from "./auth/routes.js";
import { GlobalContext } from './globals/GlobalContext.js';
const App = () => {
// variables
const [someState, setSomeState] = useState('hello world');
// render
return (
<div>
<GlobalContext.Provider value={{someState, setSomeState}}>
<Router children={Routes} basename={process.env.REACT_APP_PUBLIC_URL} />
</GlobalContext.Provider>
</div>
);
}
GlobalContext.js
import { createContext } from 'react';
export const GlobalContext = createContext("");
routes.js
import { Route, Switch } from "react-router-dom";
// views
import ViewOne from '../views/ViewOne.js';
import ViewTwo from '../views/ViewTwo.js';
// globals
import { frontendLinks } from '../globals/index.js';
export const Routes = (
<Switch>
<Route exact path={frontendLinks.viewOne} component={ViewOne}></Route>
<Route exact path={frontendLinks.viewTwo} component={ViewTwo}></Route>
</Switch>
);
now the views...
import { useContext } from 'react';
// globals
import { GlobalContext } from '../globals/GlobalContext.js';
const ViewOne = () => {
const { someState } = useContext(GlobalContext);
return (
<div>
<h1>{someState}<h1>
</div>
)
}
export default ViewOne;
and
import { useContext } from 'react';
// globals
import { GlobalContext } from '../globals/GlobalContext.js';
const ViewTwo = () => {
const { someState } = useContext(GlobalContext);
return (
<div>
<h1>{someState}<h1>
</div>
)
}
export default ViewTwo;
If you don't want to manage shared state in your app.js file, I suggest you check out this video for managing useContext state in different files > https://www.youtube.com/watch?v=52W__dKdNnU

Warning: [react-router] Location "/add" did not match any routes

I am stuck with react-router routing. I am getting the error:
Warning: [react-router] Location "/add" did not match any routes`
// conf.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link} from "react-router-dom";
import add from './add';
import { createBrowserHistory } from 'history';
import confv1 from './confv1';
var button =React.createElement(Link, {
to: "/add"
}, React.createElement("button", {
type: "button"
}, "Add a project"));
export default class Root extends Component {
render() {
return (
React.createElement(Router, {
history: createBrowserHistory()
}, React.createElement(Route, {
path: "/conf",
component: confv1
}, React.createElement(Route, {
component: conf
}), React.createElement(Route, {
path: "/add",
component: add
})
)));
// );this is the conf page
and this is the add page when I refresh it I got the error "Warning: [react-router] Location "/add" did not match any routes`"
}
}
`
I resolved the error with a routes.js
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import App from './App';
import conf from './conf';
import add from './add';
export default (
<Route path="/" component={App}>
<IndexRoute component={conf} />
<Route path="/conf" component={conf} >
<IndexRoute component={add} />
<Route path="/add" component={add} />
</Route>
</Route>
);
//index.js
import 'babel-polyfill';
import React from 'react';
import {render} from 'react-dom';
import {Router, BrowserRouter } from 'react-router';
import routes from './routes';
import {browserHistory} from 'react-router';
const history = require("history").createBrowserHistory();
render(
<Router history={browserHistory} routes={routes} />, document.getElementById('root')
)
but when I refresh the add page nothing shows in the contententer image description here
I noticed from your code snippet that you are using two different npm packages, and I am wondering if that is part of the issue.
under Config.js you called:
import { BrowserRouter as Router, Route, Link} from "react-router-dom";
Then under index.js you called:
import {Router, BrowserRouter } from 'react-router';
if that doesn't fix the issue could you create a codesandbox so I can take a look?
https://codesandbox.io/
Here is more information about the two npm packages you were trying to use:
https://www.npmjs.com/package/react-router
https://www.npmjs.com/package/react-router-dom
good luck!

MemoryRouter and jest test

https://reacttraining.com/react-router/web/guides/testing
The react-router testing documentation is bit obscure to me.
How to write a test to check a route is rendered
A Component. - APage.js
import React, { Component } from 'react'
export default class APage extends Component {
render() {
return (
<div>
A Page
</div>
)
}
}
Writing a unit test to check , as per documentation.
routes.test.js
import React from 'react'
import { render } from "react-dom";
import APage from './APage'
import {MemoryRouter} from 'react-router-dom';
test("render route", () => {
render(
<MemoryRouter initialEntries={["/apage"]}>
<APage />
</MemoryRouter>
);
});
It gives an error,
Invariant Violation: Target container is not a DOM element.
for render.
How do I write a basic test, like to test a component is rendered on a route.
I'd like to comment on Remi's solution, since the API in React Router v6 is a little different (and the link to the docs leads now to a 404):
import { Router } from 'react-router-dom';
test("render route", () => {
const history = createMemoryHistory();
render(
<Router
location={history.location} // history.location has a default value of '/'
navigator={history}
>
<APage />
</Router>
);
})
see github repo here
I think you should use Router instead. Since that uses BrowserRouter. (see alternatives section on react router example page)
import { Router } from 'react-router-dom';
test("render route", () => {
const history = createMemoryHistory();
history.push('/apage');
render(
<Router history={history}>
<APage />
</Router>
);
});
It could be that you should also add your page in a Route, but I'm not sure.
Then it would be something like:
import { Router, Route } from 'react-router-dom';
test("render route", () => {
const history = createMemoryHistory();
history.push('/apage');
render(
<Router history={history}>
<Route path='/aroute' render={(props) => (<APage {...props} />)} />
</Router>
);
});
Ok. Route testing has to be done by enzyme. not just using jest.
Followed https://medium.com/#antonybudianto/react-router-testing-with-jest-and-enzyme-17294fefd303
Used enzyme mount to test.

RouteHandler: React.createElement: type should not be null, undefined, boolean, or number

The use of RouteHanlder gives two errors:
VM2805 bundle.js:9597Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components).
Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
The structure of my application.
src
-- components
-- -- App.jsx
-- -- LengthModule.jsx
-- index.jsx
-- routes.js
My routes.js file
var React = require('react');
var Router = require('react-router');
var DefaultRoute = Router.DefaultRoute;
var Route = Router.Route;
var routes = (
<Route name="app" path="/" handler={require('./components/app.jsx')}>
<DefaultRoute handler={require('./components/LengthModule.jsx')} />
</Route>
)
index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App.jsx';
ReactDOM.render(<div><App /></div>, document.getElementById('app'));
App.jsx
import React from 'react';
import { Router, RouteHandler } from 'react-router';
export class App extends React.Component {
render () {
return <div>
<RouteHandler />
</div>;
}
}
LengthModule.jsx
import React from 'react';
import Router from 'react-router';
export class LengthModule extends React.Component {
render () {
return <div>"Hello World"</div>;
}
}
Am I using RouteHandler correctly? What am I missing? Are there any alternatives?
App.jsx
import React from 'react';
import { Router, RouteHandler } from 'react-router';
export default class App extends React.Component {
render () {
return <div>
<RouteHandler />
</div>;
}
}
LengthModule.jsx
import React from 'react';
import Router from 'react-router';
export defaulf class LengthModule extends React.Component {
render () {
return <div>"Hello World"</div>;
}
}
Why es6 react component works only with "export default"?
Newer tutorials warn: Be Careful About Deprecated Syntax. This article specifically mentions "<RouteHandler /> is Deprecated."