I have a material ui setup with SSR. I works fine...
My problem is that when I compile my code, material-ui generates some weird classnames like jss116 or jss19.
This is really annoying when inspecting my code in development. I want to have (In my development environment), more meaningful class names. Is this possible?
server.tsx
import * as path from 'path';
import * as express from "express";
import * as bodyParser from "body-parser";
import * as React from "react";
import * as ReactDOMServer from "react-dom/server";
import {StaticRouter} from "react-router";
import {matchPath} from "react-router-dom";
import {Helmet} from "react-helmet";
import { createStore, Action } from 'redux';
import { Provider } from 'react-redux';
import {SheetsRegistry, create} from 'jss';
import JssProvider from 'react-jss/lib/JssProvider';
import {MuiThemeProvider, jssPreset, createGenerateClassName} from '#material-ui/core/styles';
import App from "../shared/App";
import routes from '../shared/routes';
import theme from '../shared/MainTheme';
const app = express();
const PORT = process.env.PORT || 3000;
app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
app.use(express.static("build/public"));
console.log("Public path:", path.join(__dirname, "public"));
const appReducer = (prevState: any, action: Action) => ({...prevState, message: "Reducer"});
app.get('*', (req, res, next) => {
const now = new Date();
console.log(`GET ${now} - ${req.originalUrl}`);
const activeRoute = routes.find(route => !!matchPath(req.url, route)) || {
path: "/" };
// TODO: Fetch initial state according to the active route.
const preloadedState = {activeRoute};
const store = createStore(appReducer, preloadedState as any);
const sheetsRegistry = new SheetsRegistry();
const sheetsManager = new Map();
const generateClassName = createGenerateClassName();
const jss = create(jssPreset());
const context = {}
const content = ReactDOMServer.renderToString(
<StaticRouter location={req.url} context={context}>
<JssProvider jss={jss} registry={sheetsRegistry} generateClassName={generateClassName}>
<MuiThemeProvider theme={theme} sheetsManager={sheetsManager}>
<Provider store={store}>
<App/>
</Provider>
</MuiThemeProvider>
</JssProvider>
</StaticRouter>
);
const helmet = Helmet.renderStatic();
const css = sheetsRegistry.toString();
const html = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<style id="jss-server-side">${css}</style>
</head>
<body>
<div id="root" style="overflow-x: hidden; width: 100%; margin: 0;">${content}</div>
<script src="client_bundle.js" type="text/javascript"></script>
<script type="text/javascript">
window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\\u003c')}
</script>
</body>
</html>
`;
res.send(html);
});
app.listen(PORT, () => {
console.log(`App is running on port ${PORT}`)
})
client.tsx
import * as React from "react";
import * as ReactDOM from 'react-dom';
import {BrowserRouter, Router} from "react-router-dom";
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import {appReducer} from '../shared/reducers';
import App from "../shared/App";
import {create} from "jss";
import {createGenerateClassName, MuiThemeProvider, jssPreset} from '#material-ui/core/styles';
import theme from '../shared/MainTheme';
import JssProvider from 'react-jss/lib/JssProvider';
import configureStore from '../shared/store/index';
declare global {
interface Window {
__PRELOADED_STATE__ : any
}
}
const preloadedState = window.__PRELOADED_STATE__;
delete window.__PRELOADED_STATE__;
// const store = createStore(appReducer, preloadedState);
// const store = configureStore(appReducer, preloadedState);
const store = configureStore(preloadedState);
const Main = () => {
React
.useEffect(function didMount() {
const jssStyles = document.getElementById('jss-server-side');
if (jssStyles && jssStyles.parentNode) {
jssStyles
.parentNode
.removeChild(jssStyles);
}
}, []);
return <App/>
}
const generateClassName = createGenerateClassName();
const jss = create(jssPreset());
ReactDOM.hydrate(
<JssProvider jss={jss} generateClassName={generateClassName}>
<MuiThemeProvider theme={theme}>
<BrowserRouter>
<Provider store={store}>
<Main/>
</Provider>
</BrowserRouter>
</MuiThemeProvider>
</JssProvider>, document.querySelector('#root'),);
I finally sorted this out by running webpack like this:
webpack --mode=development ./server.ts
Turns out, for some reason, webpack doesn't listen to NODE_ENV
You should be able to get meaningful names in development by properly setting NODE_ENV in your build tool.
You could change the generateClassName props value to your custom generator based on the environment. In production, you can just use the usual createGenerateClassName.
For example:
let generateClassName = null;
if (process.env.NODE_ENV === "production") {
// use the default class name creator from mui
generateClassName = createGenerateClassName();
} else {
// make your own name generator
const createGenerateId = () => {
let counter = 0;
return (rule, sheet) => `pizza--${rule.key}-${counter++}`;
};
generateClassName = createGenerateId();
}
// ... in render
<JssProvider generateClassName={generateClassName} ...>
...
</JssProvider>
This example was taken from CSS-in-JS Docs.
I ran into this issue and fixed it by using the createGenerateClassName function and setting the disableGlobal option to true.
const generateClassName = createGenerateClassName({
disableGlobal: true,
});
const App = () => ({
<StylesProvider generateClassName={generateClassName}>...</StylesProvider>
});
Related
I'm New to nextjs and I ran into a problem I added a TawkTo and I feel like this is the reason of the error. I have imported dynamically my tawkto file in my _app.js file :
import '../styles/Home.css';
import 'bootstrap/dist/css/bootstrap.css';
import Navbar from './Navbar';
import Footer from './Footer';
import Script from 'next/script';
import Head from 'next/head';
import '#fortawesome/fontawesome-svg-core/styles.css';
import { SSRProvider } from '#react-aria/ssr';
import React from 'react';
import TawkTo from './Components/TawkTo';
import dynamic from 'next/dynamic';
function MyApp({ Component, pageProps }) {
const Countdown = dynamic(() => import("./Components/TawkTo"), {
SSR: false,
});
return (
<Head>
<link passhref="true" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossOrigin="anonymous" />
<Script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossOrigin="anonymous"></Script>
<link passhref="true" rel="preconnect" href="https://fonts.gstatic.com" crossOrigin />
</Head>,
<SSRProvider>
<React.StrictMode>
<Navbar />
<Component {...pageProps} />
<TawkTo />
<Footer />
</React.StrictMode>
</SSRProvider>
)
}
export default MyApp
and my TawkTo.js:
import React from 'react';
import { useEffect } from 'react';
const TawkTo = () => {
useEffect(() => {
// <!--Start of Tawk.to Script-->
var Tawk_API = Tawk_API || {},
Tawk_LoadStart = new Date();
(function () {
var s1 = document.createElement("script"),
s0 = document.getElementsByTagName("script")[0];
s1.async = true;
s1.src = 'https://embed.tawk.to/5d7e91079f6b7a4457e1cadb/default';
s1.charset = 'UTF-8';
s1.setAttribute('crossorigin', '*');
s0.parentNode.insertBefore(s1, s0);
})();
// <!--End of Tawk.to Script-->
}, [])
return (
<div>
{/* empty div */}
</div>
)
}
export default TawkTo
and these are the console errors I'm getting:
a little help will be so much thankful :-)
I have tried multiple solutions that were suggested in MaterialUI and NextJS official examples and forums with no luck. My page is unable to use my MUI styles on the first render and I keep getting this error:
Warning: Prop `className` did not match. Server: "makeStyles-image-3 makeStyles-image-5" Client: "makeStyles-image-4 makeStyles-image-7"
My _document.tsx:
import React from 'react';
import Document, { DocumentContext, Head, Html, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '#material-ui/core/styles';
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<meta charSet="utf-8" />
<link rel="icon" href="/favicon.ico" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
static async getInitialProps(ctx: DocumentContext) {
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({ enhanceApp: (App) => (props) => sheets.collect(<App {...props} />) });
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps, styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()] };
}
}
My _app.tsx:
import '../styles/globals.css';
import type { AppProps } from 'next/app';
import React, { useEffect } from 'react';
import { CssBaseline, ThemeProvider } from '#material-ui/core';
import Head from 'next/head';
import { theme } from '../src/app/theme';
const App: React.FC<AppProps> = ({ Component, pageProps }) => {
useEffect(() => {
const jssStyles = document.querySelector('#jss-server-side');
console.log(jssStyles?.parentElement?.removeChild(jssStyles));
jssStyles?.parentElement?.removeChild(jssStyles);
}, []);
return (
<React.Fragment>
<Head>
<title>My App</title>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
</Head>
<ThemeProvider theme={theme}>
<CssBaseline />
<Component {...pageProps} />
</ThemeProvider>
</React.Fragment>
);
};
export default App;
The solutions I've tried:
https://github.com/mui-org/material-ui/blob/0ff9cb54a9/examples/nextjs-with-typescript/README.md
https://github.com/hadnazzar/nextjs-with-material-ui/blob/master/README.md
Also many from StackOverflow similar posts (though none of the answers helped, so please do not mark this as a duplicate).
Used packages versions:
"#material-ui/core": "^4.12.3",
"next": "11.1.2",
"react": "17.0.2",
Is there anything that I'm missing here?
I am using material UI in NEXTJS and on first render sometimes its applying all the custom changes sometimes it doesn't. when it applying all those and click on link its breaking again and I did all the custom changes which mentioned https://github.com/mui-org/material-ui/blob/master/examples/nextjs here like creating custom _app.js and _document.js file
_app.js
import { useEffect, Fragment } from 'react';
import Head from 'next/head';
import PropTypes from 'prop-types';
import CssBaseline from '#material-ui/core/CssBaseline';
import { ThemeProvider } from '#material-ui/core/styles';
import theme from '../src/theme';
import "../styles/globals.css";
export default function MyApp({ Component, pageProps }){
useEffect(() => {
const jssStyles = document.querySelector('#jss-server-side');
console.log(jssStyles);
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
const getLayout = Component.getLayout || ((page) => page)
return (<>
<Head>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
</Head>
<ThemeProvider theme={theme}>
<CssBaseline />
{getLayout(<Component {...pageProps} />)}
</ThemeProvider>
</>)
}
MyApp.propTypes = {
Component: PropTypes.elementType.isRequired,
pageProps: PropTypes.object.isRequired,
};
_document.js
import * as React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import theme from '../src/theme';
import { ServerStyleSheets } from '#material-ui/core/styles'
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
{/* PWA primary color */}
<meta name="theme-color" content={theme.palette.primary.main} />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with static-site generation (SSG).
MyDocument.getInitialProps = async (ctx) => {
const originalRenderPage = ctx.renderPage;
const sheets = new ServerStyleSheets();
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => <App {...props} />,
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
};
};
any help would appreciated
I've got a Standard React-Redux Application with react router v4, webpack 4 and I'm trying to perform lazy loading of components via loadable-components library, so webpack can create chunks and load them on demand. The problems seems it's always rendering the Dashboard (refer code below) Component inside the <Switch>, no matter the route.
I don't understand the cause. I found a similar problem: React-Router v4 rendering wrong component but matching correctly but it follows a different pattern and I can't or don't understand how to apply that solution into my issue.
I'm posting The main AppContainer and the routes file:
AppContainer.js:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Provider } from 'react-redux'
import ReduxToastr from 'react-redux-toastr'
import 'react-redux-toastr/src/styles/index.scss'
import { Offline, Online } from 'react-detect-offline'
import Footer from 'components/Footer/'
import { Modal, ModalHeader, ModalBody } from 'reactstrap'
import { Translate } from 'react-redux-i18n'
import { PersistGate } from 'redux-persist/integration/react'
import { Router, Switch, Route } from 'react-router-dom'
import PrivateRoute from 'components/PrivateRoute'
import { Dashboard, PasswordReset, PasswordResetEdit, SignIn } from 'routes'
// Layout
import CoreLayout from 'layouts/CoreLayout'
class AppContainer extends Component {
static propTypes = {
history: PropTypes.object.isRequired,
persistor: PropTypes.object.isRequired, // redux-persist
store : PropTypes.object.isRequired
}
render () {
const { history, store, persistor } = this.props
const opened = true
const toastrDefaultTimeout = 8000
const newToastrAlwaysOnTop = false
return (
<div>
<Online>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<div style={{ height: '100%' }}>
<ReduxToastr
timeOut={toastrDefaultTimeout}
newestOnTop={newToastrAlwaysOnTop}
preventDuplicates
position='top-right'
transitionIn='fadeIn'
transitionOut='fadeOut'
progressBar />
<Router history={history}>
<CoreLayout {...this.props} >
<Switch>
<Route exact path='/sign-in' component={SignIn} />
<Route exact path='/passwords/new' component={PasswordReset} />
<Route exact path='/passwords/edit' component={PasswordResetEdit} />
<PrivateRoute exact path='/' component={Dashboard} persistor={persistor} />
</Switch>
</CoreLayout>
</Router>
</div>
</PersistGate>
</Provider>
</Online>
<Offline>
<div className='app'>
<div className='app-body'>
<main className='main align-items-center align-self-center'>
<div className='container'>
<div className='animated fadeIn'>
<Modal isOpen={opened} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}><Translate value={`views.shared.no-internet.title`} /></ModalHeader>
<ModalBody>
<div className='card-block'>
<div className='row'>
<div className='col-sm-12'>
<Translate value='views.shared.no-internet.description' />
</div>
</div>
</div>
</ModalBody>
</Modal>
</div>
</div>
</main>
</div>
<Footer />
</div>
</Offline>
</div>
)
}
}
export default AppContainer
routes/index.js:
// We only need to import the modules necessary for initial render
import loadable from 'loadable-components'
import { hot } from 'react-hot-loader'
// Component split-code (lazy load)
let Dashboard,
SignIn,
PasswordReset,
PasswordResetEdit
// Needed for HMR
if (__DEV__) {
Dashboard = hot(module)(loadable(() => import('./Dashboard')))
PasswordReset = hot(module)(loadable(() => import('./PasswordReset')))
PasswordResetEdit = hot(module)(loadable(() => import('./PasswordResetEdit')))
SignIn = hot(module)(loadable(() => import('./SignIn')))
} else {
Dashboard = loadable(() => import('./Dashboard'))
SignIn = loadable(() => import('./SignIn'))
PasswordReset = loadable(() => import('./PasswordReset'))
PasswordResetEdit = loadable(() => import('./PasswordResetEdit'))
}
export { Dashboard, PasswordReset, PasswordResetEdit, SignIn }
And for anyone curious, here is the PrivateRoute component:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Route, Redirect } from 'react-router-dom'
import { connect } from 'react-redux'
import { validateSession } from 'modules/sessions/session'
const mapStateToProps = state => ({
session: state.session
})
const mapDispatchToProps = (dispatch) => {
return {
validateSession: () => { dispatch(validateSession()) }
}
}
class PrivateRoute extends Component {
componentDidMount () {
this.props.validateSession(this.props.persistor)
}
render () {
const { component: Component, session, ...rest } = this.props
return (
<Route {...rest} render={(routeProps) =>
this.props.session.userSignedIn ? <Component {...routeProps} />
: <Redirect to={{
pathname: '/sign-in',
state: { from: routeProps.location }
}} />
}
/>)
}
}
PrivateRoute.propTypes = {
component: PropTypes.func.isRequired,
persistor: PropTypes.object.isRequired,
session: PropTypes.object.isRequired,
validateSession: PropTypes.func.isRequired
}
export default connect(mapStateToProps, mapDispatchToProps)(PrivateRoute)
If I remove the if (_DEV_) block in routes/index.js and always do it like the 'else' block everything works okay, however I lose HMR, meaning I have to refresh the browser to see code changes take effect.
Edit
For anyone wandering where the history prop comes from:
Main app entry point (in webpack.config.js). src/main.js:
import React from 'react'
import ReactDOM from 'react-dom'
import createStore from './store/createStore'
import { hot } from 'react-hot-loader'
import AppContainer from './containers/AppContainer'
import { persistStore } from 'redux-persist'
// ========================================================
// Store Instantiation
// ========================================================
const initialState = window.___INITIAL_STATE__
const { history, store } = createStore(initialState)
// begin periodically persisting the store
let persistor = persistStore(store)
// ========================================================
// Render Setup
// ========================================================
const MOUNT_NODE = document.getElementById('root')
let render = () => {
ReactDOM.render(
<AppContainer store={store} persistor={persistor} history={history} />,
MOUNT_NODE
)
}
// This code is excluded from production bundle
if (__DEV__) {
if (module.hot) {
// Development render functions
const renderApp = render
const renderError = (error) => {
const RedBox = require('redbox-react').default
ReactDOM.render(<RedBox error={error} />, MOUNT_NODE)
}
// Wrap render in try/catch
render = () => {
try {
renderApp()
} catch (error) {
console.error(error)
renderError(error)
}
}
// Setup hot module replacement
module.hot.accept('./containers/AppContainer', () =>
render(require('./containers/AppContainer').default)
)
}
}
// ========================================================
// Go!
// ========================================================
export default hot(module)(render)
render()
createStore.js:
import { applyMiddleware, compose, createStore } from 'redux'
import thunk from 'redux-thunk'
import { apiMiddleware } from 'redux-api-middleware'
import { createLogger } from 'redux-logger'
import makeRootReducer from './reducers'
import { routerMiddleware } from 'react-router-redux'
// I18n
import { syncTranslationWithStore, loadTranslations, setLocale } from 'react-redux-i18n'
import { translationsObject } from 'translations/index'
// Router history
import createHistory from 'history/createBrowserHistory'
// Raven for Sentry
import Raven from 'raven-js'
import createRavenMiddleware from 'raven-for-redux'
export default (initialState = {}) => {
// ======================================================
// Middleware Configuration
// ======================================================
const logger = createLogger()
const history = createHistory()
const historyMiddleware = routerMiddleware(history)
const middleware = [historyMiddleware, apiMiddleware, thunk, logger]
if (__PROD__) {
Raven.config(`${__SENTRY_DSN__}`).install()
middleware.push(createRavenMiddleware(Raven))
}
// ======================================================
// Store Enhancers
// ======================================================
const enhancers = []
let composeEnhancers = compose
const composeWithDevToolsExtension = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
if (typeof composeWithDevToolsExtension === 'function') {
composeEnhancers = composeWithDevToolsExtension
}
// ======================================================
// Store Instantiation and HMR Setup
// ======================================================
const store = createStore(
makeRootReducer(),
initialState,
composeEnhancers(
applyMiddleware(...middleware),
...enhancers
)
)
store.asyncReducers = {}
// DEPRECATED in react-router v4: To unsubscribe, invoke `store.unsubscribeHistory()` anytime
// store.unsubscribeHistory = browserHistory.listen(updateLocation(store))
if (module.hot) {
const reducers = require('./reducers').default
module.hot.accept('./reducers', () => {
store.replaceReducer(reducers(store.asyncReducers))
})
}
syncTranslationWithStore(store)
store.dispatch(loadTranslations(translationsObject))
store.dispatch(setLocale('es_AR'))
return { history, store }
}
I'm stuck with this codes,
index.html
<!doctype html>
<html lang="en">
<head>
<title>React Redux Starter Kit</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<div id="root" style="height: 100%"></div>
<div id="demo"></div>
</body>
</html>
Counter.js
import React from 'react'
import {core as Core} from 'zingchart-react'
export const Counter = React.createClass({
render () {
var myConfig = {
type: "bar",
series : [
{
values : [35,42,67,89,25,34,67,85,90.99]
}
]
};
return(
<div>Hello
<Core id="myChart" height="300" width="600" data={myConfig} />
</div>
)
}
})
export default Counter
main.js
import React from 'react'
import ReactDOM from 'react-dom'
import createBrowserHistory from 'history/lib/createBrowserHistory'
import { useRouterHistory } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
import createStore from './store/createStore'
import AppContainer from './containers/AppContainer'
import Counter from './components/Counter/Counter'
ReactDOM.render(<Counter/>, document.querySelector('#demo'));
// ========================================================
// Browser History Setup
// ========================================================
const browserHistory = useRouterHistory(createBrowserHistory)({
basename: __BASENAME__
})
// ========================================================
// Store and History Instantiation
// ========================================================
const initialState = window.___INITIAL_STATE__
const store = createStore(initialState, browserHistory)
const history = syncHistoryWithStore(browserHistory, store, {
selectLocationState: (state) => state.router
})
if (__DEBUG__) {
if (window.devToolsExtension) {
window.devToolsExtension.open()
}
}
const MOUNT_NODE = document.getElementById('root')
let render = (routerKey = null) => {
const routes = require('./routes/index').default(store)
ReactDOM.render(
<AppContainer
store={store}
history={history}
routes={routes}
routerKey={routerKey}
/>,
MOUNT_NODE
)
}
if (__DEV__ && module.hot) {
const renderApp = render
const renderError = (error) => {
const RedBox = require('redbox-react')
ReactDOM.render(<RedBox error={error} />, MOUNT_NODE)
}
render = () => {
try {
renderApp(Math.random())
} catch (error) {
renderError(error)
}
}
module.hot.accept(['./routes/index'], () => render())
}
render()
I am using react-redux starter kit - https://github.com/davezuko/react-redux-starter-kit, I'm getting this error, please help me out.
ERROR: Cannot read property '__reactAutoBindMap' of undefined
This is the es6 way of writing your component:
import React from 'react';
import {core as Core} from 'zingchart-react';
class Counter extends React.Component {
render () {
var myConfig = {
type: "bar",
series : [
{
values : [35,42,67,89,25,34,67,85]
}
]
};
return (
<div>Hello
<Core id="myChart" height="300" width="600" data={myConfig} />
</div>
)
}
}
export default Counter;
and to render it,
ReactDOM.render(<Counter />, document.getElementById('some_div'));
core is not a valid name for a React Component. React Components must start with an upper case letter, that is how React distinguish between components and HTML tags.
So your code should look like this
import React from 'react'
import {core as Core} from 'zingchart-react'
export const Counter = React.createClass({
render () {
var myConfig = {
type: "bar",
series : [
{
values : [35,42,67,89,25,34,67,85]
}
]
};
return (
<div>Hello
<Core id="myChart" height="300" width="600" data={myConfig} />
</div>
)
}
})
export default Counter
working example