I am new to React and I am building my first application with React, Redux, and React Router, so far I have successfully set up my boiler plate, however when I want to use React-Router and create routes I get the following error
TypeError: Cannot read property 'string' of undefined
./node_modules/react-router-dom/es/BrowserRouter.js
node_modules/react-router-dom/es/BrowserRouter.js:38
35 | }(React.Component);
36 |
37 | BrowserRouter.propTypes = {
> 38 | basename: PropTypes.string,
39 | forceRefresh: PropTypes.bool,
40 | getUserConfirmation: PropTypes.func,
41 | keyLength: PropTypes.number,
This only happens when I try to import and use
import { BrowserRouter, Route } from 'react-router-dom';
Here is my index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store'
import { BrowserRouter, Route } from 'react-router-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
class Hello extends Component {
render(){
return(
<div>Hello</div>
)
}
}
class GoodBye extends Component {
render(){
return(
<div>GoodBye</div>
)
}
}
ReactDOM.render(<Provider store={store}>
<BrowserRouter>
<Route path="/hello" component={Hello}/>
<Route path="/goodbye" component={GoodBye}/>
</BrowserRouter>
</Provider>, document.getElementById('root'));
registerServiceWorker();
And my package.json
{
"name": "reactreduxrouterblog",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.16.2",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-redux": "^5.0.6",
"react-router": "^2.0.0-rc5",
"react-router-dom": "^4.0.0",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
"redux-promise-middleware": "^4.4.1",
"redux-thunk": "^2.2.0"
},
"devDependencies": {
"react-scripts": "1.0.14"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
Any knowledge will be welcomed thanks!
Update your react-router-dom in package.json: react-router-dom ^4.2.2
Sometimes it may cause due to incompatible versions of "react-router-dom" and "react-router-prop-types". For me it worked with following configuration.
react-router-dom:"^4.2.2",
react-router-prop-type:"^3.2.1"
Try adding the PropTypes package to your app.
basename: PropTypes.string
Looks like you are just missing that package.
EDIT:
Be sure to run npm install to install all dependencies.
import React from 'react'; <--as normal
import PropTypes from 'prop-types'; <--add this as a second line
App.propTypes = {
monkey: PropTypes.string, <--omit "React."
cat: PropTypes.number.isRequired <--omit "React."
};
//Wrong: React.PropTypes.string
//Right: PropTypes.string
Related
hi I am getting this warning and I want this warning to be solved and wouldn't be displayed on the console tab so I could upload my code to netlify and as far as I have read the documentation and policies of netlify, it says warnings and errors may be the reason that it can't be uploaded so I need this to be solved
index.js file
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter, Route, Link } from 'react-browser-router';
import "../src/assets/css/index.scss";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
reportWebVitals();
package.json
{
"name": "daryaft-yar",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"axios": "^1.1.3",
"lodash": "^4.17.21",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-browser-router": "^2.1.2",
"react-cookie": "^4.1.1",
"react-dom": "^18.2.0",
"react-icons": "^4.6.0",
"react-paginate": "^8.1.4",
"react-scripts": "5.0.1",
"sass": "^1.55.0",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
app.js
import './App.css';
import { Switch, Route, Redirect } from 'react-router-dom';
import React, { Component } from 'react';
import Shop from './Components/shop-bot/shop';
import Home from './Components/shop-bot/botHome';
import Coin from './Components/Coin/coin';
import Wallet from './Components/Wallet/wallet';
import AddCoin from './Components/AddCoin/add-coin';
import Cart from './Components/cart/cart';
import FinalCart from './Components/final-cart/final-cart';
import UserForm from './Components/user-from/user-form';
class App extends Component {
componentDidMount() {
}
render() {
return (
<React.Fragment>
<Switch >
<Route path="/bot/shop" component={Shop}/>
<Route path="/bot/home" component={Home} />
<Route path="/bot/coin" component={Coin} />
<Route path="/bot/buy-coin" component={AddCoin} />
<Route path="/bot/wallet" component={Wallet} />
<Route path="/bot/cart" component={Cart} />
<Route path="/bot/cart-final" component={FinalCart} />
<Route path="/bot/user-data" component={UserForm} />
<Redirect from="/" exact to="/bot/shop" />
</Switch>
</React.Fragment>
);
}
}
export default App;
I'll be honest, "react-browser-router": "^2.1.2", in the package.json file seems like a mistake.
I don't think it's necessary
You are missing react-router-dom as a dependency.
I suggest uninstalling react-browser-router and installing react-router-dom#5 so the Switch and Redirect components can still be imported. Installing the latest RRDv5 is important since there are potential issues with react#18 and the React.StrictMode component and RRDv5 versions below v5.3.3, and if you don't specify v5 then the latest v6 version will be installed which has a lot of breaking changes.
From the terminal in the root project directory run:
npm uninstall --save react-browser-router
npm install --save react-router-dom#5
Update the index.js file to import the BrowserRouter from react-router-dom.
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
import "../src/assets/css/index.scss";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
From here you should restart the app locally to ensure all is well and working before deploying the app again.
I'm creating a React project and I want to implement the BrowserRouter but the problem is that when I used it, it always throw the React Error of:
***Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.***
I don't know what is this about, because as far as I know, I'm not using hooks and I read the documentation and other tutorials to solve this problem (like deleting double react or npm link and that's stuff) but this still a problem.
Here are my files.
App.js
import { BrowserRouter, Route, Routes, Link } from "react-router-dom";
import Navbar from "./components/navbar"
import Login from "./components/login";
// import CreateExercise from "./components/create-exercise.component";
// import CreateUser from "./components/create-user.component";
function App() {
return (
// <h1>HOASNKFNLSA</h1>
// <div>
// <Home/>
// </div>
<BrowserRouter>
<Routes>
<Route path="/" render={() => {
<h1>HOKAKSFNAKSO</h1>
}}>
</Route>
</Routes>
</BrowserRouter>
);
}
function Home() {
return (
<div className="container text-center">
<h1>KEVIN STYLE PELUQUERIA</h1>
</div>
);
}
function About() {
return (
<div>
<h2>About</h2>
</div>
);
}
function Dashboard() {
return (
<div>
<h2>Dashboard</h2>
</div>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
package.json
{
"name": "kevin-style-peluqueria",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.16.1",
"#testing-library/react": "^11.2.7",
"#testing-library/user-event": "^12.8.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"web-vitals": "^1.1.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
I don't know if you need anything else, but if you do, ask me in comments. If you need to know more extra info, I'm not using webpack. I'm using the classic React structure application when you do the command npx create-react-app. I'm also using express and MongoDB like my backend (basically I'm creating an application with the MERN Stack).
You should do something like this.
And take a look to the docs with examples
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter as Router } from 'react-router-dom'
ReactDOM.render(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
As many other people have had the same issue, I'm struggling to interact with a <Link> element to change routes and render a new component. I am able to click on the link and the path for my application changes in my redux store, but no component gets updated. My root component does not seem to respond to shouldComponentUpdate, even though props are changing and the full setup is similar to how connected-react-router describes it needs to be.
To test
The sample code (git repo) is a MVP (minimum viable product) - it can easily replicate the problem I am seeing.
git clone https://github.com/reZach/electron-webpack-template.git
cd electron-webpack-template
npm i
npm run dev
If you'd prefer to look at files, I've included the necessary files below
index.js
import React from "react";
import ReactDOM from "react-dom";
import Root from "../app/components/core/root";
import store, { history } from "./redux/store/store";
ReactDOM.render(
<Root store={store} history={history}></Root>,
document.getElementById("root")
);
store.js
import { configureStore, getDefaultMiddleware } from "#reduxjs/toolkit";
import { createBrowserHistory } from "history";
import { routerMiddleware } from "connected-react-router";
import rootReducer from "../reducers/rootReducer";
export const history = createBrowserHistory();
const store = configureStore({
reducer: rootReducer(history),
middleware: [...getDefaultMiddleware(), routerMiddleware(history)]
});
export default store;
root.jsx
import React from "react";
import { ConnectedRouter } from "connected-react-router";
import { Provider, connect } from "react-redux";
import Routes from "../core/routes";
class Root extends React.Component {
render() {
return (
<Provider store={this.props.store}>
<ConnectedRouter history={this.props.history}>
<Routes></Routes>
</ConnectedRouter>
</Provider>
);
}
}
export default Root;
routes.jsx
import React from "react";
import { Switch, Route } from "react-router";
import routes from "../../constants/routes";
import App from "../app/app";
import Page2 from "../page2/page2";
class Routes extends React.Component {
render() {
return (
<Switch>
<Route path={routes.ENTRY} component={App}></Route>
<Route path={routes.MAIN} component={Page2}></Route>
</Switch>
);
}
}
export default Routes;
routes.json
{
"ENTRY": "/",
"MAIN": "/main"
}
package.json
{
"name": "electron-webpack-template",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "npm run build-dev-webpack && npm run start-dev-app",
"build-dev-webpack": "webpack --mode development --config ./app/configs/webpack/webpack.config.js",
"start-dev-app": "cross-env NODE_ENV=development electron app/main.js",
"prod": "npm run build-prod-webpack && npm run start-prod-app",
"build-prod-webpack": "webpack --mode production --config ./app/configs/webpack/webpack.config.js",
"start-prod-app": "cross-env NODE_ENV=production electron app/main.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/reZach/electron-webpack-template.git"
},
"keywords": [],
"author": "",
"license": "GPL-3.0-only",
"bugs": {
"url": "https://github.com/reZach/electron-webpack-template/issues"
},
"homepage": "https://github.com/reZach/electron-webpack-template#readme",
"devDependencies": {
"#babel/core": "^7.7.7",
"#babel/plugin-proposal-json-strings": "^7.7.4",
"#babel/plugin-transform-react-jsx": "^7.7.7",
"#babel/preset-env": "^7.7.7",
"babel-loader": "^8.0.6",
"cross-env": "^6.0.3",
"csp-html-webpack-plugin": "^3.0.4",
"devtron": "^1.4.0",
"electron": "^7.1.7",
"html-webpack-plugin": "^3.2.0",
"lockfile-lint": "^3.0.5",
"webpack": "^4.41.4",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.1"
},
"dependencies": {
"#reduxjs/toolkit": "^1.2.1",
"connected-react-router": "^6.6.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-redux": "^7.1.3",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"redux": "^4.0.5"
}
}
This is probably because there is no "exact" word on the Entry route (for App component):
<Switch>
<Route exact path={routes.ENTRY} component={App}></Route>
<Route path={routes.MAIN} component={Page2}></Route>
</Switch>
The solution to these routing woes was to add the exact attribute as drazewski suggested, and in addition change the history object I was using for my <ConnectedRouter>. The problem was caused by me using createBrowserHistory and the fact that I am not using a webserver in my application to host my files. The default path of my application when loading my app was file:///C:/...index.html. This is the path value when I looked in my Redux store when the app loaded.
I had to change to use createHashHistory instead, which works when you are not hosting a webserver to host your app. The default path when using createHashHistory is a /, which matches routes.ENTRY in my routes.jsx file and allows me to navigate to /main. Apparently, you can't navigate to another path unless your path matches an existing path you define in your <Route>s (this is what I think what was happening as I described my problem above - although I don't know why my home/page1 component rendered at all then...).
Here
are good references that pointed me in the direction that I had to change my history (here and here). In addition to those links, here is a good blog post (mirror) explaining more in-detail the various types of history for react-router.
new routes.jsx
import React from "react";
import { Switch, Route } from "react-router";
import routes from "../../constants/routes";
import App from "../app/app";
import Page2 from "../page2/page2";
class Routes extends React.Component {
render() {
return (
<Switch>
<Route exact path={routes.ENTRY} component={App}></Route> <!-- updated -->
<Route path={routes.MAIN} component={Page2}></Route>
</Switch>
);
}
}
export default Routes;
new store.js
import { configureStore, getDefaultMiddleware } from "#reduxjs/toolkit";
import { createHashHistory } from "history"; // < updated!
import { routerMiddleware } from "connected-react-router";
import rootReducer from "../reducers/rootReducer";
export const history = createHashHistory(); // < updated!
const store = configureStore({
reducer: rootReducer(history),
middleware: [...getDefaultMiddleware(), routerMiddleware(history)]
});
export default store;
I'm trying to hook up a Container to the redux store but I get this error:
Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: object.
Check the render method of Route.
I'm trying to follow the instructions here:
https://react-redux.js.org/using-react-redux/connect-mapdispatch
My attempts are commented out at the bottom. Swapping either for the normal export default statement produces this error but the normal way works fine so I know this is a problem with connect.
My container:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import axios from 'axios';
//import { bindActionCreators } from 'redux'
import queryString from 'query-string';
import { signIn } from "../actions";
class MomentumContainer extends Component {
state = {display: "Waiting"};
componentWillMount() {
const query = queryString.parse(this.props.location.search);
console.log(`query: ${JSON.stringify(query)}`);
if(query.user_id) {
console.log(`User logged in w/ id: ${query.user_id}`);
//this.props.dispatch(signIn(query.user_id));
}
}
async componentDidMount() {
const dev = process.env.REACT_APP_DEV_SERVER_ENDPOINT;
const prod = process.env.REACT_APP_PROD_SERVER_ENDPOINT;
const base_endpoint = process.env.REACT_APP_DEV_MODE ? dev : prod;
const api_endpoint = `${base_endpoint}momentum`;
//TODO above can be handled on app startup and managed by redux??
//console.log(api_endpoint);
const response = await axios.get(api_endpoint);
this.setState({display: response.data});
}
render() {
return <h1>{this.state.display}</h1>
}
}
// // Tried this
// const actionCreators = { signIn };
// export default connect(null, actionCreators)(MomentumContainer);
// // Tried this
//export default connect()(MomentumContainer);
// This works
export default MomentumContainer;
My index.js file:
import React from "react";
import ReactDOM from "react-dom";
import {Provider} from "react-redux";
import {createStore, compose, applyMiddleware} from "redux";
import thunk from "redux-thunk";
import promise from 'redux-promise-middleware';
import logger from "redux-logger";
import registerServiceWorker from "./registerServiceWorker";
import "./index.css";
import App from "./App";
import {BrowserRouter, Route, Switch} from "react-router-dom";
import reducers from './reducers';
import MomentumContainer from "./containers/MomentumContainer";
const { REACT_APP_DEV_MODE } = process.env;
const dev_mode = JSON.stringify(REACT_APP_DEV_MODE) === JSON.stringify("true");
const middleware = applyMiddleware(promise, thunk, logger);
let store_dev;
if (dev_mode === true) {
console.log('App starting in development mode.');
const allStoreEnhancers = compose(
middleware,
window.devToolsExtension && window.devToolsExtension()
);
store_dev = createStore(reducers, {}, allStoreEnhancers)
} else {
console.log('App starting in production mode');
}
const store_production = createStore(reducers, {}, middleware);
const store = dev_mode ? store_dev : store_production;
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<Switch>
<Route path="/" exact component={App} />
<Route path="/Momentum" exact component={MomentumContainer} />
</Switch>
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
registerServiceWorker();
My package.json:
{
"name": "ticker-alert-frontend",
"version": "0.1.0",
"private": true,
"dependencies": {
"#material-ui/core": "^3.9.3",
"ajv": "^6.10.0",
"axios": "^0.18.0",
"materialize-css": "^1.0.0-rc.2",
"query-string": "^6.1.0",
"react": "^16.8.6",
"react-dom": "^16.4.0",
"react-redux": "^7.0.3",
"react-router-dom": "^4.3.1",
"react-scripts": "1.1.4",
"redux": "^4.0.1",
"redux-logger": "^3.0.6",
"redux-promise": "^0.6.0",
"redux-promise-middleware": "^6.1.0",
"redux-thunk": "^2.3.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
Any help/suggestions would be greatly appreciated!
After reading here (https://github.com/ReactTraining/react-router/issues/4354) about a similar issue, and seeing a suggestion to update react-router-dom, I tried updating that package to version 5.0.0 from 4.3.1 and it didn't work.
After updating the rest of my packages by running npm update --save my app is working. If anyone is having a similar problem I recommend running this command.
I'm working on a project to integrate React and Golang together. I've made a first try and everything works as expected. But now I'm using webpack with babel-loader to generate my bundle.js and the program crash and i can't figoure out why.
When i type webpack in CLI, he send me this error:
Hash: 80aee336cd31d922b888
Version: webpack 4.16.4
Time: 261ms
Built at: 2018-08-03 16:05:28
1 asset
Entrypoint main = ./bundle.js
[0] ./index.js 647 bytes {0} [built] [failed] [1 error]
ERROR in ./index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: Unexpected token (9:16)
7 | }
8 |
> 9 | ReactDOM.render(<App />, document.getElementById('root'));
| ^
10 |
That's my index.js who cause failure
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App.jsx';
ReactDOM.render(<App />, document.getElementById('root'));
My package.json:
{
"name": "rtsupport",
"version": "1.0.0",
"description": "Realtime support frontend",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "G Descamps <gauthier1.descamps#gmail.com>",
"license": "ISC",
"dependencies": {
"react": "^16.4.2",
"react-dom": "^16.4.2",
"webpack-command": "^0.4.1"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"react": "^16.4.2",
"react-dom": "^16.4.2",
"serve": "^9.4.0",
"webpack": "^4.16.4",
"webpack-cli": "^3.1.0",
"webpack-command": "^0.4.1",
"webpack-dev-server": "^3.1.5"
}
}
And my webpack.config.js:
const webpack = require("webpack");
const path = require("path");
let config= {
entry:'./index.js',
output: {
path:__dirname,
filename:'./bundle.js'
},
module: {
rules:[{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader'
}]
}
}
module.exports= config;
Here's my Github Repo if you need to see other file https://github.com/LaLauque/RealTimePlatform/tree/dev/rtsupport
Thanks a lot
your App component does not has any render() { ... } function at here : https://github.com/LaLauque/RealTimePlatform/blob/dev/rtsupport/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App.jsx';
class App extends React.Component {
}
ReactDOM.render(<App />, document.getElementById('root'));
just render something and then check if it bundles add render function inside your App component like this:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App.jsx';
class App extends React.Component {
render() {
return(
<div>
Hello
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
also this App component will override the App component you importing from
import App from './components/App.jsx';
make sure to have specific names for each components....