Invalid hook call and it drove me crazy? - reactjs

Hello ,I am new to React and Now I would like to use MATERIAL-UI in my project but I got this error. Help me, please.
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 Have Index.js Component:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import registerServiceWorker from "./registerServiceWorker";
ReactDOM.render(
<React.Fragment>
<App />
</React.Fragment>,
document.getElementById("root")
);
registerServiceWorker();
and App.js is the functional Component:
import React from 'react'
import Layout from './Layout/Layout'
function App() {
return <Layout/>
}
export default App
and Styles.js Component from material-ui:
import { makeStyles } from "#material-ui/styles";
const useStyles = makeStyles({
root: {
display: "flex",
height: "100vh",
width: "100%",
},
rightSidebar: {
background: "#BDC3C7",
width:'18%'
},
leftSidebar: {
background: "#BDC3C7",
width:'25%'
},
mainPart: {
background: "#BDC3C7",
flex:1
},
});
export default useStyles;
and Layout.js Component is:
import React from "react";
import useStyles from "./Styles";
function Layout() {
const classes = useStyles();
return (
<div className={classes.root}>
<div className={classes.rightSideba}>right side bar</div>
<div className={classes.mainPart}>main part</div>
<div className={classes.leftSidebar}>left side bar</div>
</div>
);
}
export default Layout;
Thank you

Start simple: What React / React DOM versions do you have?
Then: Does your environment (browser?) start multiple instances of React / React DOM? (esp. any older ones dangling around)

Related

Modal Form: react__WEBPACK_IMPORTED_MODULE_0__.createPortal is not a function

I'm working on shopping Cart app, I want to use a Modal Form to display the cart's content and additional options before place the order, that's why I'm using Portals, so far, the source code of my Modal.js looks like this:
import { Fragment } from 'react';
import ReactDOM from 'react';
//import ReactDOM from 'react-dom/client';
import classes from './Modal.module.css';
const Backdrop = (props) => {
return <div className={classes.backdrop} onClick={props.onClose}/>;
};
const ModalOverlay = (props) => {
return (
<div className={classes.modal}>
<div className={classes.content}>{props.children}</div>
</div>
);
};
const portalElement = document.getElementById('overlays');
const Modal = (props) => {
return (
<Fragment>
{ReactDOM.createPortal(<Backdrop onClose={props.onClose} />, portalElement)}
{ReactDOM.createPortal(
<ModalOverlay>{props.children}</ModalOverlay>,
portalElement
)}
</Fragment>
);
};
export default Modal;
When I tried to load the modal form -clicking on an icon- I get this error:
This is the React's version I'm using:
This code used to work on previous version of React (17.x), the weird thing I tried to downgrade but still getting the same error.
My questions are:
In ver 18.x of React, Portals have been changed?
How can I downgrade React properly in order to test my code?
do you have any other suggestions how to overcome this issue using React's 18?
Thanks a lot
I had same error and I solved by importing
import ReactDOM from 'react-dom';
instead of
import ReactDOM from 'react-dom/client';

How to fix React forwardRef(Menu) Material UI?

I created very simple custom components MuiMenu and MuiMenuItem. But when I try displaying these components I see an error as shown below:
Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
Check the render method of `ForwardRef(Menu)`.
But if I import directly from #material-ui/core - all is well. How do I fix this?
Working example:
https://codesandbox.io/s/sharp-shadow-bt404?file=/src/App.js
As the error says, Material-UI is using ForwardRef and you need to include that in your code. Below is a fix to your MuiMenu and MuiMenuItem Components;
MuiMenu
import React from "react";
import Menu from "#material-ui/core/Menu";
const MuiMenu = React.forwardRef((props, ref) => {
return <Menu ref={ref} {...props} />;
});
export default MuiMenu;
MuiMenuItem
import React from "react";
import MenuItem from "#material-ui/core/MenuItem";
const MuiMenuItem = React.forwardRef((props, ref) => {
return <MenuItem ref={ref} {...props} />;
});
export default MuiMenuItem;
Also there was an error with the strictmode you used at index so I removed it.
Index.JS
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<App />,
rootElement
);
here is a link to the fixed sandbox: https://codesandbox.io/s/hopeful-thunder-u6m2k
And here are other links to help you understand a bit more: https://material-ui.com/getting-started/faq/#how-do-i-use-react-router | https://reactjs.org/docs/react-api.html#reactforwardref

How do i configure makeStyles hook in material-ui with a custom jss insertion point?

I have a react component which i have wrapped & released as a web component. However all style-sheets created using makeStyles hook are not getting applied as the are inserted into the head section of the browser DOM.
Is there a way for me to configure the makeStyles hook and supply the shadowRoot as a the insertion point for the jss??
import React from "react";
import ReactDOM from "react-dom";
import { create as createJss } from "jss";
import preset from "jss-preset-default";
import { StylesProvider, jssPreset } from "#material-ui/styles";
import Content from "./Content";
const jss = createJss();
jss.setup({
...jssPreset(),
insertionPoint: document.getElementById("jss-insertion-point")
});
function App() {
return (
<JssProvider jss={jss}>
<Content />
</JssProvider>
<div id="jss-insertion-point"></div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Also see https://codesandbox.io/s/61qjy83qzz?file=/src/index.js:0-739 by Robin Ednam
Also https://github.com/cssinjs/jss/issues/466
Your component or main app component should be wrapped in
Got this done and working to Jitsi app now

how to snapshot from component created with material ui styles in way that styles would be in snapshot

I am using material-UI in my react web app.
I want to test my component with jest in way that styles would be saved in snapshot of component like what jest-styled-component do for styled-component but I cant.
you can see my sample project in codesandbox
but here are the important parts:
I create my project with create-react-app with this command:
npx create-react-app myapp
this is my index.js file:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {MuiThemeProvider} from '#material-ui/core/styles';
import theme from './customTheme';
ReactDOM.render(
<MuiThemeProvider theme={theme}>
<App/>
</MuiThemeProvider>,
document.getElementById('root')
);
this is my customTheme.js file in src folder:
import {createMuiTheme} from '#material-ui/core/styles';
const theme = createMuiTheme({
typography: {
fontFamily: [
'Roboto',
'"Segoe UI"',
'"Helvetica Neue"',
'Arial',
'sans-serif',
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"',
].join(','),
},
palette: {
color: 'blue',
}
});
export default theme;
and this is my App.js that I want to test:
import React from 'react';
import PropTypes from 'prop-types';
import {withStyles} from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
export const styles = theme => ({
mystyle: {
fontFamily: theme.typography.fontFamily,
border: '1px solid green',
background: 'yellow',
color: theme.palette.color,
},
});
function MyComponent(props) {
const {classes} = props;
return (
<div>
<p className={classes.mystyle}> my text </p>
<Button className={classes.mystyle}>my button</Button>
</div>
);
}
MyComponent.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(MyComponent);
please notice that I am overwriting styles with JSS and I have my own theme.
I want to get snapshot from component in way that css be part of snapshot like this issue from material-UI's repository in github or like what jest-styled-component-do for styled-component. for reaching that goal I wrote this code in my demo.test.js:
import React from "react";
import renderer from "react-test-renderer";
import App from '../App';
import {styles} from '../App';
describe("snapshot test", () => {
it("should match snapshot", () => {
const wrapper = renderer
.create(<App classes={styles}/>)
.toJSON();
expect(wrapper).toMatchSnapshot();
});
});
but with this test my styles are not in snapshot therefore if I change mystyle in App component the snapshot test will not fail.
I have read bellow resources but couldn't get what I wanted:
https://github.com/mui-org/material-ui/issues/9492
https://github.com/mui-org/material-ui/issues/6834
thanks for any feedback

Adding slimscroll to reactJS

I am trying to add Slimscroll to a ReactJS app and I see the scrollbar reflect in the browser dev tools but I am getting an error in the console and the UI is breaking. AS a sidenote, the app compiles successfully.
This is my App.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { connect } from 'react-redux';
import classnames from 'classnames';
import 'jquery-slimscroll/jquery.slimscroll.min';
import injectTapEventPlugin from 'react-tap-event-plugin';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
class App extends Component {
componentDidMount() {
$(".scroll").slimscroll({
height: '100%'
});
}
render() {
<MuiThemeProvider muiTheme={getMuiTheme(materialUITheme)}>
<div id="app-inner">
....blah blah blah....
</div>
</MuiThemeProvider>
};
}
module.exports = App;
Then in the index.html I added the scroll class to the <body>
I intend to use this on other places with an overflow like scrolling tables or lists, so I'd rather have the slimscroll function attached to a utility class I can re-use (i.e. scroll)
As you can see below, the slimscroll is passing to the DOM
But the UI breaks because ReactJS doesn't like the method I used in some way.
Lots of things not working (i.e. the menu, the page displays partially, etc)
How can I add slimscroll to ReactJS. I looked at react-scrollbar in npm but it requires to wrap the element in <ScrollBar></ScrollBar> and I can't do that to the body
This might not be a direct answer to your question. But it will solve your original problem. IMO It's not a good idea to use jQuery plugins with React. But you can use react-scrollbar as your main container without no visual difference from adding scrolls to the body. Here is a small example.
import React from 'react';
import { render } from 'react-dom';
import { Scrollbars } from 'react-custom-scrollbars';
const App = () => (
<Scrollbars style={{ height: "100vh" }}>
<div style={{height:"2000px"}}/>
</Scrollbars>
);
render(<App />, document.getElementById('root'));
Also, make sure your html and body have no margins.
html, body{
margin: 0px;
}
Working Example: https://codesandbox.io/s/orLx4ZlL

Resources