Using react-loadable with renderToNodeStream - reactjs

I'm new to the react-loadable library. I am wondering if it is possible to use React's renderToNodeStream instead of renderToString on the server.
server index.js:
/* code... */
const appWithRouter = (
<Loadable.Capture report={moduleName => modules.push(moduleName)}>
<Provider store={store}>
<StaticRouter location={req.path} context={context}>
<div>{renderRoutes(Routes)}</div>
</StaticRouter>
</Provider>
</Loadable.Capture>
);
let bundles = getBundles(stats, modules);
const htmlStream = renderToNodeStream(appWithRouter);
res.status(200).write(renderHeader(htmlStream)); /* wrong ??? */
htmlStream.pipe(res, { end: false });
htmlStream.on('end', () => {
res.write( renderFooter(store, bundles) );
res.end();
});
});
Loadable.preloadAll().then(() => {
app.listen(PORT, () => console.log(`listening on port: ${PORT}`));
});
render.js file imported into index.js:
export const renderHeader = (content) => {
console.log('content in renderHeader: ', content);
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/styles.css">
<title>Title</title>
</head>
<body>
<div id="app">${content}</div>`;
}
export const renderFooter = (store, bundles) => {
return `<script>
window.INITIAL_STATE = ${JSON.stringify(store.getState())}
</script>
<script src="/vendor.js"></script>
${bundles.map(bundle => {
return `<script src="/${bundle.file}"></script>`}).join('\\n')}
<script src="/app.js"></script>
</body>
</html>
`;
}
I have not found any examples or patterns the use the renderToNodeStream only renderToString. Is this close or way off? I would like to be able to use renderToNodeStream to get a faster response.

Related

TypeError: Cannot destructure property 'html' of '(intermediate value)' as it is undefined

I am creating a NextJS app using MUI and Styledcomponents. I still don't understand why but tutorials tell I need to create a _document.tsx file to work with it and during the creation of this file, which i did following a tutorial indeed, I found this
TypeError: Cannot destructure property 'html' of '(intermediate value)' as it is undefined.
29 | });
30 | }
> 31 | const initialProps = await Document.getInitialProps(ctx);
| ^
32 | return {
33 | ...initialProps,
34 | styles: (
and this is the whole _document.tsx file:
import React from "react";
import Document, { Html, Head, Main, NextScript } from "next/document";
import { ServerStyleSheet } from "styled-components";
import theme from "#/styles/theme";
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
MyDocument.getInitialProps = async (ctx) => {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = ():any => {
originalRenderPage({
enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props}/>),
});
}
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
}finally {
sheet.seal()
}
}

NextJs + MaterialUI - prop `className` did not match

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?

Problem with jquery(react-owl-carousel) in gatsby/react

please help. I was trying to use react-owl-carousel in a gatsby site but I have run into a problem. The error says:
Here's my gatsby-node.js
exports.onCreateWebpackConfig = ({ plugins, actions }) => {
actions.setWebpackConfig({
plugins: [
plugins.define({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
}),
],
})
}
try this in your gatsby-node.js
exports.onCreateWebpackConfig = ({ actions }) => {
const { setWebpackConfig } = actions
setWebpackConfig({
externals: {
jquery: 'jQuery', // important: 'Q' capitalized
},
})
}
and in html.js
import React from 'react'
import PropTypes from 'prop-types'
export default function HTML(props) {
return (
<html {...props.htmlAttributes}>
<head>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossOrigin="anonymous"
/>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
</body>
</html>
)
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
}
put html.js in the src folder

Error: _registerComponent(...): Target container is not a DOM element

I understand that the error is because i'm trying to render the elements to a DOM that isnt loaded yet, I've checked multiple questions on stackoverflow but i cant seem to figure out where my issue lies. In the Webpack-dev-server my code works perfectly and there's no problem. Now i'm running server.js with nodejs and i'm getting this error.
Below are the html, bundle.js and app.js files
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React Login System</title>
<link rel="stylesheet" type="text/css" href="login.css">
</head>
<body>
<div id="root"></div>
<script src="./bundle.js"></script>
</body>
</html>
//bundle.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(<App />, document.getElementById('root'))
//app.js
import React, { Component } from 'react'
import { Router, Route, Link, IndexRoute, hashHistory, browserHistory } from 'react-router'
import LoginPage from './login'
const NotFound = () => (<h1>404.. This page is not found!</h1>)
var App = React.createClass({
render() {
return (
<Router history={hashHistory}>
<Route path='/' component={LoginPage} />
<Route path='/verify/:token' component={EmailValidation} />
<Route path='*' component={NotFound} />
</Router>
)
}
});
var EmailValidation = React.createClass({
getInitialState: function(){
return {
verifyResponse: null,
valid: false,
displayResult: "Uh-oh something went wrong."
};
},
setResponse : function(e){
this.setState({
verifyResponse: e
});
switch(this.state.verifyResponse){
case 'found':
console.log("response rcvd, valid is true");
this.setState({
valid: true,
displayResult: "Your email has been verified."
});
break;
case 'negative':
this.setState({
valid: false
});
break;
}
},
componentDidMount : function(){
var token = this.props.params.token;
let fetchData = {
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: null,
token: this.props.params.token,
message: null
})
}
var fromServer = fetch('http://MyIpAddress/verify', fetchData)
.then(response => response.json())
.then(response => {
this.setResponse(response.message);
})
.catch(error => console.log("there was an error --> " + error));
},
render() {
return (
<div>
<p> {this.state.displayResult} </p>
</div>
)
}
});
export default App

Unable to implement ZingChart-React

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

Resources