Invalid hook call error when wrapping MuiThemeProvider within App - javascript

I get the following error when I wrap MuiThemeProvider in App.js. The page will not load at all. I've used it similarly in other projects, so not sure why this is happening.
react.development.js:1476 Uncaught 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
App.js
import React from 'react'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import Home from './views/Home'
import ProjectDetailsForm from './components/ProjectDetailsForm/ProjectDetailsForm'
import { MuiThemeProvider } from '#material-ui/core/styles'
import theme from './styles/theme'
function App() {
return (
<MuiThemeProvider theme={theme}>
<Router>
<div className="app">
<Routes>
<Route
path="/"
element={[
<Home key="1"></Home>,
<ProjectDetailsForm key="2"></ProjectDetailsForm>
]}></Route>
</Routes>
</div>
</Router>
</MuiThemeProvider>
)
}
export default App
theme.js
// import { common } from '#material-ui/core/colors'
import { createTheme } from '#material-ui/core/styles'
// import { black } from '#mui/material/colors'
const theme = createTheme({
components: {
MuiFormLabel: {
styleOverrides: {
root: {
color: '#000'
}
}
},
MuiInputLabel: {
styleOverrides: {
root: {
color: '#000'
}
}
}
}
})
export default theme

This issue can happen when you're React tries to load twice. For example, if I make my own library that uses React, and then import it locally into a project that also uses React. What's in this file ./components/ProjectDetailsForm/ProjectDetailsForm'?

Solved:
I realized I hadn't yet installed #material-ui/core. Once I tried, I was getting 'could not resolve dependency errors'. Had to use legacy MUI dependencies due to conflicts with React 18.
Found the fix here

Related

'Router'/'GlobalStyles' cannot be used as a JSX component

I'm having this issue on my React application:
'Router' cannot be used as a JSX component.
Its instance type 'Router' is not a valid JSX element.
The types returned by 'render()' are incompatible between these types.
It's also happening on a Global Styles component I created
'GlobalStyles' cannot be used as a JSX component.
Its instance type 'Component<ThemedGlobalStyledClassProps<{}>
This is my App.tsx file:
import {BrowserRouter, Router} from 'react-router-dom';
import { Slide, ToastContainer } from "react-toastify";
import Routes from "./routes";
import GlobalStyles from "./styles/global";
import Header from "./components/Header";
import Aside from "./components/Aside";
import { CartProvider } from "./hooks/useCart";
import history from "./history";
import { AuthProvider } from "./Context/AuthContext";
const App = (): JSX.Element => {
return (
<>
<Aside />
<AuthProvider>
<Router history={history}>
<CartProvider>
<GlobalStyles />
<Header />
<Routes />
<ToastContainer autoClose={3000} transition={Slide} />
</CartProvider>
</Router>
</AuthProvider>
</>
);
};
export default App;
I'm using the version 18 of React and there's what I've tried so far:
Deleting node_modules and running yarn install
Reverting React version to 17~
Reinstalling React and React Router
First at all you have to import BrowserRouter as Router like the following code:
import { BrowserRouter as Router, } from "react-router-dom";
GlobalStyles probably it not a component.
Here two way to create a component in React.
1-) Function Components must be like following:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
2-) Class Components:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Your styled-components might be using old versions of #types/react. You can confirm by checking the version of react types in node_modules/types/styled-components.
For me adding yarn resolutions helped to solve the problem (if you are using yarn as well).
Try adding this to your package.json file.
"resolutions": {
"#types/react": "^18.0.0"
}
Unfortunately it will (might???) not work if you are using npm.

Uncaught Error: You are loading the CommonJS build of React Router on a page that is already running the ES modules build, so things won't work right

I am trying using this BrowserRoute in my App.js , it is giving me the following error since a long time , unable to resolve this please help me with this.I have installed react-router-dom#5
Here is my code for App.js
import react from 'react'
import Homepage from "./Pages/Homepage"
import ChatPage from "./Pages/ChatPage"
import { Route } from 'react-router-dom';
import { BrowserRouter } from 'react-router-dom/cjs/react-router-dom.min';
function App() {
return (
<div className="App">
<BrowserRouter>
<Route exact path = "/" component = {Homepage}/>
<Route exact path = "/chats" component = {ChatPage}/>
</BrowserRouter>
</div>
);
}
export default App;
import { Route, BrowserRouter } from 'react-router-dom';

Is it OK to fetch data in App.js? (to conditionally render views)

I would like to know more about the standards of setting upp a React app, the do's and don'ts.
To conditionally allow a user to visit a page or not, could I for example fetch data in App.js (or even index.js?) to then conditionally render the Router links?
To me it sounds bad to do fetching in App.js but that might not matter at all. I guess the idea is that it could slow down the app or make the code less readable.
Any thoughts on this? Or any place I can read more about this.
Code example might help:
//App.js
import React, { useState } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { useQuery, gql } from '#apollo/client';
import NavBar from './components/NavBar';
import Start from './views/Start';
import Approvals from './views/Approvals';
const GET_USERINFO = gql`
query {
userRole {
canApproveReports
}
}
`;
function App() {
const { data } = useQuery(GET_USERINFO);
return (
<Router>
<NavBar />
<Route exact path="/" component={start} />
// THE GOOD STUFF
{data?.userRole.CanApproveReports && (
<Route exact path="/approvals" component={approvals} />
)}
</Router>
);
}
export default App;

react-redux-react-router v4 url, updates but the component does not

First off, I have read through just about every example I can find and looked through various boilerplates to see how others have done this. I am having issues loading pages when clicking <Link>'s with react-router v4. I have also installed the package react-router-connected and have been trying that out as well but no improvement can be seen (however it shows the changes in the redux-logger which is nice).
Currently, the url updates just fine and if I manually change the url and press enter, then the next page will load. But, it will not redirect if I click a link. I am also using create-react app for the project, just for your reference. My actual app is setup as the exact example from usage with react-router in the official redux docs. For simplicity, I have changed my routes to only include links to basic components that do nothing but redirect to one another.
Root.js which houses my routes
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router'
// import App from './App';
import NewComponent from './NewComponent';
import OldComponentent from './OldComponent';
const Root = ({ store, history }) => (
<Provider store={store}>
<ConnectedRouter history={history}>
<Router>
<Switch>
<Route exact path='/' component={OldComponentent}/>
<Route path='/new' component={NewComponent}/>
{/* <Route path='/' component={App}/>
<Route path='/:filter' component={App}/> */}
</Switch>
</Router>
</ConnectedRouter>
</Provider>
)
export default Root;
Home component
import React from 'react';
import { connect } from 'react-redux';
import { push } from 'connected-react-router';
import { withRouter } from 'react-router';
import { Link } from 'react-router-dom';
import Button from 'material-ui/Button';
class OldComponent extends React.Component {
redirectPage = () => { this.props.dispatch(push('/new')); };
redirectPage1 = () => { this.props.dispatch(push('/')); };
render() {
return (
<div>
OLD COMPONENT
<Button onClick={this.redirectPage}>Redirect new</Button>
<Button onClick={this.redirectPage1}>Redirect /</Button>
<Link to='/new'>Redirect Link</Link>
</div>
)
}
}
export default withRouter(connect()(OldComponent));
Other basic component for redirection purposes
import React from 'react';
import { connect } from 'react-redux';
import { push } from 'connected-react-router';
import { withRouter } from 'react-router';
import { Link } from 'react-router-dom';
import Button from 'material-ui/Button';
class NewComponent extends React.Component {
redirectPage = () => { this.props.dispatch(push('/')); };
redirectPage1 = () => { this.props.dispatch(push('/new')); };
render() {
return (
<div>
NEW COMPONENT
<Button onClick={this.redirectPage}>Redirect /</Button>
<Button onClick={this.redirectPage1}>Redirect new</Button>
<Link to='/new'>Redirect Link</Link>
</div>
)
}
}
export default withRouter(connect()(NewComponent));
As you can see, they are essentially the same component with minor differences. The url will change to /new or / and will also update the pathname found in the ##router/LOCATION-CHANGE state objects created by react-router-connected package. The url will also change by clicking the <Link> tag but with no redirect.
Any help on how to approach this would be greatly appreciated.
The comment posted by #Supertopoz works this.props.history.push('/pathname') works. However, after setting that up, the <Link> now works as well. I am also using withRouter (which I was before) throughout, so that was another important factor in egtting it to work.

"Objects are not valid as a React child" appear only in IE

Objects are not valid as a React child. If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Root.
This bug only appear in IE, i know a react child can't be an object, but i can't find any error in Root class
// Root.js
import React, { Component, PropTypes } from 'react'
import { Provider } from 'react-redux'
import { Router, browserHistory } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
import routes from './routes'
export default class Root extends Component {
render() {
const { store } = this.props
const history = syncHistoryWithStore(browserHistory, store)
return (
<Provider store={store}>
<div>
<Router history={history} routes={routes} />
</div>
</Provider>
)
}
}
// routes.js
import React from 'react'
import { Route } from 'react-router'
import Cookie from './libs/cookie'
import App from './app'
import MobileRouter from './routes/mobile'
import WebRouter from './routes/web'
export default (
<Route path="/" component={App}>
{ WebRouter }
{ MobileRouter }
</Route>
)
// App.js
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { browserHistory } from 'react-router'
class App extends Component {
constructor(props) {
super(props)
}
render() {
const { children } = this.props
return (
<div>
{ children }
</div>
)
}
}
Why
If you are using react-hot-loader v3 for hot-reloading in DEV environment you need to load react-hot-loader/patch after babel-polyfill does.
So Webpack's entry field should look like the following to work correctly with react 15.4.x, react-hot-loader v3 and webpack-dev-server.
Fix
entry: [
'babel-polyfill', // Load this first
'react-hot-loader/patch', // This package already requires/loads react (but not react-dom). It must be loaded after babel-polyfill to ensure both react and react-dom use the same Symbol.
'react', // Include this to enforce order
'react-dom', // Include this to enforce order
'./index.js' // Path to your app's entry file
]
Use
It is very useful to test a feature in your DEV environment on IE. You can now access your local app, with webpack running, on IE from a VM, local network, ngrok, etc.
“Objects are not valid as a React child” appear only in IE
Not true. This error will appear in all browsers if you use an object. You mostly likely have something like the following in your code
{someBool && someObj}
where someBool is only coming out true based on how your application state is in IE. if you did the same actions in any other browser you will get the same error.
Fix
Don't render an object. React can't handle it. And is giving you the correct error which you should fix i.e render something from the obj e.g.
{someBool && someObj.someStringProp}

Categories

Resources