I'm trying to create a npm package - a UI component.
Let's say I have a project called fancy-web, and the npm package called fancy-components.
In fancy-web, I include in package.json
"fancy-components": "^0.0.1"
( In other words, fancy-web will consume fancy-components ).
In fancy-web, I have
// ...
import { ThemeProvider } from 'styled-components';
import { Testing } from 'fancy-components';
// ...
return (
<ThemeProvider theme={theme}>
<Testing />
</ThemeProvider>
)
The problem is here
In my fancy-components Testing component, if I'm doing
If I'm doing something trivial like this in the Testing component, I will get an error
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:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
---
import React from 'react';
import styled from 'styled-components';
const Container = styled.div`
margin-top: 40px;
`;
function Testing(props: Props): JSX.Element {
return (
<Container>
<div>Testing</div>
</Container>
);
}
export default Testing;
However, the following works if my "Testing" component just like that.
The following is the `Testing` code
---
import React from 'react';
import styled from 'styled-components';
function Testing(props: Props): JSX.Element {
return (
<div>Testing</div>
);
}
export default Testing;
Not sure what is wrong here and really appreciated of any help.
It turns out because I'm doing linking which cause the issues. After I push it out instead of doing linking, everything works fine.
Related
I am working on a React project (react#18.2.0, styled-components#5.1.1) that has been set up to use styled-components so that commonly used components are exported from a common/styled.js file, but that causes a great amount of invalid hook call errors.
Right now, it looks something like this:
export const ExampleButton = styled.button`
color: white;
`;
And then those styled componets are imported where needed, like this:
import { ExampleButton, SomeComponent, AnotherComponent } from '../common.styled';
I know they invalid hook calls are caused by this export/import setup, because the error message for one particular styled component goes away when I remove it from common/styled.js and instead paste it locally everywhere it's needed, so that instead of this:
import { ExampleButton } from '../common.styled';
const ExampleComponent = () => {
return (
<div>
<ExampleButton>Hello</ExampleButton>
</div>
);
};
I do this:
import styled from 'styled-components';
const ExampleComponent = () => {
const ExampleButton = styled.button`
color: white;
`;
return (
<div>
<ExampleButton>Hello</ExampleButton>
</div>
);
};
So that works, but it's not really a viable solution, because I would have to paste the same code everywhere, not just ExampleComponent, and doing that for the whole project would result in a massive amount of code repetition.
What is the right way to create a solution similar to common/styled.js here in a way that doesn't break the Rules of Hooks?
It seems that there had been an issue between some older versions of styled-components and React 18 that have been solved in v5.3.1.
https://github.com/styled-components/styled-components/pull/3564
Maybe upgrading styled-components to v5.3.1 or higher would solve the issue.
I'm using Stitches to write my CSS in a React application, mainly for the theming and variables. I'm calling createStitches in every component file, like so:
ComponentA.tsx
import { createStitches, styled } from "#stitches/react";
const { createTheme } = createStitches({ theme: {...} });
...
export default ComponentA;
ComponentB.tsx
import { createStitches, styled } from "#stitches/react";
const { createTheme } = createStitches({ theme: {...} });
...
export default ComponentB;
And then I'm importing these components and using them in App.tsx:
import ComponentA from "./components/ComponentA";
import ComponentB from "./components/ComponentB";
function App() {
return (
<div className='App'>
<ComponentA />
<ComponentB />
</div>
)
}
I know I can just call the createStitches in the App.tsx file once, but I like keeping my components self-sufficient, as in they should work without any other extra work. Is this a bad approach, or is this something that is fine to do? Does React call the function many times, or just once? Thanks for any help!
You do not need to call createStitches for every component. This function is to create configuration for your application styling. I don't that you are going to have separate configuration for every component.
This will just cause extra work. Just keep the createStitches in a common file and import it from there
I'm new to react and I'm trying to using makestyles and this is how :
in Header.jsx :
import React from "react";
import UseStyles from "./Header_style";
function Header() {
const classes =UseStyles();
return (
<div className={"Main-Header"}>
<div className={"Header-Logo"}>
<div className={classes.test}>test</div>
</div>
</div>
);
};
export default Header;
and style.js :
import {makeStyles} from '#material-ui/styles';
const UseStyles = makeStyles(theme=>({
test: {
backgroundColor: '#BDC3C7',
color :'red !important',
widtH : '18%'
},
}));
export default UseStyles;
but I'm getting folwing error:
×
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:
*edit:
This is how I'm using Header :
import React, { Component } from 'react'
import Header from './component/heder/Header.jsx';
class App extends Component {
constructor() {
super();
this.state = {
monsters: [],
searchField: ''
};
}
render() {
return (
<Header/>
);
}
}
export default App;
and another thing, I'm getting following error too :
When you place your Header component in the return or render of a parent component make sure you use <Header /> and not {Header}
additionally if that's not the problem you can check this link which is the official react thread on that error.
Also posting how you render the component that is throwing the error would be very helpful.
Edit* Additionally you don't need to call makeStyles with a function. Since you are not using the theme, you can just call makeStyles with an object like this
const useStyles = makeStyles({
test: {
background: 'white',
width: '100%'
}
});
EDIT and additional answers:
Here's a snippet from MUI's official page on styles:
The way you import makeStyles:
import { makeStyles } from '#material-ui/styles
If you import this way you have to have applied the #material-ui/styles module.
If instead in your package.json you use '#material-ui/core and haven't installed #material-ui/styles you could be getting that error because you don't have the module #material-ui/styles.
If you just have #material-ui/core you can still import makeStyles without installing the standalone #material-ui/styles it is all included in #material-ui/core.
Simply import it like this instead:
import { makeStyles } from '#material-ui/core/styles'
everybody, I've found the solution!
have to use withStyles.
I have imported useStats into my index page but when I use it it breaks gatsby/react and I get this error:
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 fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
I tried to trouble shoot using this from the site:
// Add this in node_modules/react-dom/index.js
window.React1 = require('react');
// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);
But I got back true.
Here is my code:
import React, { useState } from "react";
import { Link } from "gatsby";
// components
import Layout from "../components/Layout/Layout";
import SEO from "../components/seo";
import IndexComponent from "../components/IndexComponent/IndexComponent";
const IndexPage = () => {
const [sku] = useState();
return (
<Layout>
<SEO title="Home" />
<IndexComponent />
</Layout>
);
};
export default IndexPage;
1.) you need [sku, setSku] = useState().
2.) Where are you rendering IndexPage? Are you doing IndexPage() instead of <IndexPage />?
I think It is a terminal Issue with windows.
Seams to work fine with bash.
EDIT: I installed the v1.0.0.36 beta version and copied the sample from that versions docs (which looks identical to me) and it worked straight away. Not sure what the problem was but thanks for replies
I am trying to use Material-UI's withTheme to access the theme in a component.
I have followed the sample in the docs which goes through the create-react-app packager ok but in the browser gives the error: TypeError: Object(...) is not a function
and highlights the code line > 17 | export default withTheme()(WithTheme);
I have cut down the sample code to the most basic use of withTheme() and am still receiving this error
withtheme.js
import React from 'react';
import { withTheme } from 'material-ui/styles';
function WithTheme() {
const styles = {
primaryText: {
color: 'red',
}
};
return (
<h1 style={styles.primaryText}>Hello</h1>
);
}
export default withTheme()(WithTheme);
EDIT: To help clarify the problem, here is the App.js file.
import React, { Component } from 'react';
import './App.css';
import 'typeface-roboto';
import AppBar from 'material-ui/AppBar';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import {brown500, brown900} from 'material-ui/styles/colors';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import WithTheme from './components/withtheme';
const Theme = getMuiTheme({
palette: {
primary1Color: brown900,
primary2Color: brown500,
}
});
class App extends Component {
render() {
return (
<MuiThemeProvider muiTheme={Theme} >
<AppBar
title="Title"
iconClassNameRight="muidocs-icon-navigation-expand-more" />
<WithTheme />
</MuiThemeProvider>
);
}
}
export default App;
I have customised the theme and changed primary1Color to brown, using muiThemeProvider. This all works fine when I remove the WithTheme component from App.js - the AppBar is brown as expected. The problem is I am getting the error when I try to use the mui withTheme function.
My intention is to set the h2 in WithTheme component to be whatever color the current theme has for primary1Color
**End Edit
Any help would be appreciated. Happy to post the (almost) exact copy of the doco sample code which achieves the same error if required.
Thanks
As MaterialUI is no longer in Beta, the spec has changed a bit, outdating Liam's answer. Per the Material-UI
v3.1.2 docs
import { withTheme } from '#material-ui/core/styles';
export default withTheme()(WithTheme);
As of Material 4, the spec was changed a bit again: https://material-ui.com/styles/api/#withtheme-component-component (thus outdating Awnage's answer too).
So now it is:
import { withTheme } from '#material-ui/styles';
export default withTheme(MyComponent);
No need to use withStyles() unless if you want to make a specific style for the component
Warp your App with MuiThemeProvider then you are able to use the theme properly
Material-Ui 0.20.0
For access theme colors use getMuiTheme
import getMuiTheme from 'material-ui/styles/getMuiTheme';
export default muiThemeable()(App)
http://www.material-ui.com/#/components/app-bar
Working Demo
Material-Ui 1.0.0 beta
For access theme colors use withTheme
import { withTheme } from 'material-ui/styles';
export default withTheme()(App)
https://material-ui-next.com/demos/app-bar/
Working Demo V1
If you intend to change the theme of material-ui, I would prefer using getMuiTheme. Refer http://www.material-ui.com/#/customization/themes for documentation. What happens here is, you are styling your component with JavaScript and hence the export requires withStyles to be called.
export default withStyles(styles)(WithTheme);