I used material-ui@next as server side render and do all things as the documents. But my console says
Warning: Failed child context type: Invalid child context `64a55d578f856d258dc345b094a2a2b3` of type `Jss` supplied to `JssProvider`, expected instance of `Jss`.
in JssProvider (at server.js:274)
Here are the code around line 274
````
const jss = create(preset());
jss.options.createGenerateClassName = createGenerateClassName;
const rootComponent = (
<JssProvider registry={sheetsRegistry} jss={jss}>
<MuiThemeProvider theme={theme} sheetsManager={new Map()}>
<App context={context} store={store}>
{route.component}
</App>
</MuiThemeProvider>
</JssProvider>
);
````
Is there some things wrong? Thanks for help.
As far as I know, @kof plan an making the contextType constraint more permissive.
This warning is coming from a duplicated version of jss. Make sure you are using the same one.
Maybe we should be using jss as a peer dependency.
As far as I know, @kof plan an making the contextType constraint more permissive.
I did, will release with the next react-jss version
@oliviertassinari Thanks for help,
@oliviertassinari I'm getting the same error but with a different setup.
I'm trying to bring the new material-ui to my existing next.js project. I have followed the example at
Material UI next.js examplr
Warning: Failed prop type: Invalid prop `jss` of type `Jss` supplied to `JssProvider`, expected instance of `Jss`.
in JssProvider (at _document.js?entry:63)
in Unknown
in AppContainer
in Container
in div
in App
Warning: Failed prop type: Invalid prop `registry` of type `SheetsRegistry` supplied to `JssProvider`, expected instance of `SheetsRegistry`.
in JssProvider (at _document.js?entry:63)
in Unknown
in AppContainer
in Container
in div
in App
Warning: Failed context type: Invalid context `64a55d578f856d258dc345b094a2a2b3` of type `Jss` supplied to `Component`, expected instance of `Jss`.
in withStyles(AppWrapper) (at withRoot.js:50)
in MuiThemeProvider
in MuiThemeProviderWrapper (at withRoot.js:46)
in withRoot(withStyles(Component)) (at _document.js?entry:64)
in JssProvider (at _document.js?entry:63)
in Unknown
in AppContainer
in Container
in div
in App
Everything works exactly as expected except for these warning that I get. The only difference that my setup has is I'm using custom server ExpressJS besides next.js but I'm not sure how it causes these warnings to show up. Here is my server code. Should I follow ExpressJS integration as documented on the website or Next.js example should be enough.
const { configureRoutes } = require('./routes');
const dev = process.env.NODE_ENV !== 'production';
const logger = require('./utilities/logger').logger;
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare()
.then(() => {
const server = express();
server.use(compress());
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));
// Routes should be configured here.
configureRoutes(server);
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen(3000, (err) => {
if (err) throw err;
logger.info('>>>> Ready on http://localhost:3000');
});
})
.catch((ex) => {
logger.error(ex.stack);
process.exit(1);
});
Maybe you should check whether you inject css directly into context, my warnings occur here.
@WenXuanYuan I followed the example and basically have two main files:
getContext.js
// @flow weak
/* eslint-disable no-underscore-dangle */
/* Code is taken from https://github.com/callemall/material-ui/blob/v1-beta/examples/nextjs/styles/getContext.js */
import { create, SheetsRegistry } from 'jss';
import preset from 'jss-preset-default';
import { createMuiTheme } from 'material-ui/styles';
import purple from 'material-ui/colors/purple';
import green from 'material-ui/colors/green';
import createGenerateClassName from 'material-ui/styles/createGenerateClassName';
const theme = createMuiTheme({
palette: {
primary: purple,
secondary: green,
},
});
// Configure JSS
const jss = create(preset());
jss.options.createGenerateClassName = createGenerateClassName;
function createContext() {
return {
jss,
theme,
// This is needed in order to deduplicate the injection of CSS in the page.
sheetsManager: new Map(),
// This is needed in order to inject the critical CSS.
sheetsRegistry: new SheetsRegistry(),
};
}
export default function getContext() {
// Make sure to create a new store for every server-side request so that data
// isn't shared between connections (which would be bad)
if (!process.browser) {
return createContext();
}
// Reuse context on the client-side
if (!global.__INIT_MATERIAL_UI__) {
global.__INIT_MATERIAL_UI__ = createContext();
}
return global.__INIT_MATERIAL_UI__;
}
And _document.js which is the top document for all Nextjs pages
/**
* This document will be used to overide the head of all of your htmls,
so we can include bundle.css here.
*/
import Document, { Head, Main, NextScript } from 'next/document';
import React from 'react';
import JssProvider from 'react-jss/lib/JssProvider';
import getContext from '../utils/getContext';
class MyDocument extends Document {
render() {
return (
<html lang="en" dir="ltr">
<Head>
<title>My page</title>
<meta charSet="utf-8" />
{/* Use minimum-scale=1 to enable GPU rasterization */}
<meta
name="viewport"
content={
'user-scalable=0, initial-scale=1, ' +
'minimum-scale=1, width=device-width, height=device-height'
}
/>
{/*
{/* PWA primary color */}
<meta
name="theme-color"
content={this.props.stylesContext.theme.palette.primary[500]}
/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" />
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
);
}
}
MyDocument.getInitialProps = (ctx) => {
// Resolution order
//
// On the server:
// 1. page.getInitialProps
// 2. document.getInitialProps
// 3. page.render
// 4. document.render
//
// On the server with error:
// 2. document.getInitialProps
// 3. page.render
// 4. document.render
//
// On the client
// 1. page.getInitialProps
// 3. page.render
// Get the context to collected side effects.
const context = getContext();
const page = ctx.renderPage(Component => props => (
<JssProvider registry={context.sheetsRegistry} jss={context.jss}>
<Component {...props} />
</JssProvider>
));
return {
...page,
stylesContext: context,
styles: (
<style
id="jss-server-side"
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: context.sheetsRegistry.toString() }}
/>
),
};
};
export default MyDocument;
These are all copied from the official examples, the only difference that I have is custom Express integration that I pasted the code above. I really can't tell what I should change.
I got this error too. And I find it everything OK when I using my mac during server rending, css will generate. But on windows, the sheetsRegistry.toString only generate css once. And after the first time, I will never get css generated. what's the promble?
My server rendering code here:
const serialize = require('serialize-javascript')
const ejs = require('ejs')
const asyncBootstrap = require('react-async-bootstrapper').default
const ReactDomServer = require('react-dom/server')
const Helmet = require('react-helmet').default
const SheetsRegistry = require('react-jss').SheetsRegistry
const createJss = require('jss').create
const preset = require('jss-preset-default').default
const getStoreState = (stores) => {
return Object.keys(stores).reduce((result, storeName) => {
result[storeName] = stores[storeName].toJson()
return result
}, {})
}
module.exports = (bundle, template, req, res) => {
return new Promise((resolve, reject) => {
const createStoreMap = bundle.createStoreMap
const createApp = bundle.default
const routerContext = {}
const stores = createStoreMap()
const sheetsRegistry = new SheetsRegistry()
const jss = createJss(preset())
const app = createApp(stores, routerContext, sheetsRegistry, jss, req.url)
asyncBootstrap(app).then(() => {
if (routerContext.url) {
res.status(302).setHeader('Location', routerContext.url)
res.end()
return
}
const helmet = Helmet.rewind()
const state = getStoreState(stores)
const content = ReactDomServer.renderToString(app)
console.log(sheetsRegistry.toString())
const html = ejs.render(template, {
appString: content,
initialState: serialize(state),
meta: helmet.meta.toString(),
title: helmet.title.toString(),
style: helmet.style.toString(),
link: helmet.link.toString(),
materialCss: sheetsRegistry.toString(),
})
res.send(html)
resolve()
}).catch(reject)
})
}
and my enrty is here:
import React from 'react'
import { StaticRouter } from 'react-router-dom'
import { Provider, useStaticRendering } from 'mobx-react'
import { JssProvider } from 'react-jss'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles'
import { lightBlue, pink } from 'material-ui/colors'
import createGenerateClassName from 'material-ui/styles/createGenerateClassName'
import App from './views/App'
import { createStoreMap } from './store/store'
// 让mobx在服务端渲染的时候不会重复数据变换
useStaticRendering(true)
const theme = createMuiTheme({
palette: {
primary: pink,
accent: lightBlue,
type: 'light',
},
})
export default (stores, routerContext, sheetsRegistry, jss, url) => {
jss.options.createGenerateClassName = createGenerateClassName
return (
<Provider {...stores}>
<StaticRouter context={routerContext} location={url}>
<JssProvider registry={sheetsRegistry} jss={jss}>
<MuiThemeProvider theme={theme}>
<App />
</MuiThemeProvider>
</JssProvider>
</StaticRouter>
</Provider>
)
}
export { createStoreMap }
@hesamd I am so sorry, I also don't know where is the problem.
@WenXuanYuan I have fixed this warning! )) You just need to use jss from react-jss/lib/jss
// import { create, SheetsRegistry } from 'jss';
// import preset from 'jss-preset-default';
import { createMuiTheme } from 'material-ui/styles';
import { purple, green } from 'material-ui/colors';
import createGenerateClassName from 'material-ui/styles/createGenerateClassName';
import jss, { SheetsRegistry } from 'react-jss/lib/jss';
const theme = createMuiTheme({
palette: {
primary: purple,
secondary: green,
},
});
// console.log(jss, _jss);
// Configure JSS
// const jss = create(preset());
jss.options.createGenerateClassName = createGenerateClassName;
export const sheetsManager = new Map();
export default function createContext() {
return {
jss,
theme,
// This is needed in order to deduplicate the injection of CSS in the page.
sheetsManager,
// This is needed in order to inject the critical CSS.
sheetsRegistry: new SheetsRegistry(),
};
}
@modelfak
what about preset() ?
your fix removes the warning but it's not working as expected
@modelfak :+1:
@modelfak did you resolve the preset issue? Gary
I'm having the same issue right now, following the create-react-app demo.
@aislanmaia Thanks for raising. It should be fixed with e485be3b268e1692824543274cf4289127fde871.
@oliviertassinari in your first comment, you mentionned moving jss to peerDependencies. This would totally make sense sine we might want to use a different version in our application.
Most helpful comment
I'm having the same issue right now, following the create-react-app demo.