Reputation: 7739
I am using Semantic-UI React and Next.JS but it appears at breakpoint < 768px, my Home component completely breaks upon a refresh of the browser. I know because its a react/next.js app they are taking care of the routing but I guess I wondered what if a user happen to do that?
It doesn't happen on my /login, /register or /profile routes
So I've checked around to solve my issue — Here and in that post it points to the React docs; the explanation for why this happens and the prescription to solve it doesn't seem to fit to my case.
Same as render(), but is used to hydrate a container whose HTML contents were rendered by ReactDOMServer. React will attempt to attach event listeners to the existing markup.
React expects that the rendered content is identical between the server and the client. It can patch up differences in text content, but you should treat mismatches as bugs and fix them. In development mode, React warns about mismatches during hydration. There are no guarantees that attribute differences will be patched up in case of mismatches. This is important for performance reasons because in most apps, mismatches are rare, and so validating all markup would be prohibitively expensive.
If a single element’s attribute or text content is unavoidably different between the server and the client (for example, a timestamp), you may silence the warning by adding suppressHydrationWarning={true} to the element. It only works one level deep, and is intended to be an escape hatch. Don’t overuse it. Unless it’s text content, React still won’t attempt to patch it up, so it may remain inconsistent until future updates.
If you intentionally need to render something different on the server and the client, you can do a two-pass rendering. Components that render something different on the client can read a state variable like this.state.isClient, which you can set to true in componentDidMount(). This way the initial render pass will render the same content as the server, avoiding mismatches, but an additional pass will happen synchronously right after hydration.
This is entry point file: pages/index
import React from 'react'
import Head from '../components/head'
import HomeLayout from '../components/Home/Home.jsx'
import 'semantic-ui-css/semantic.min.css'
import '../styles/styles.scss'
import { connect } from 'react-redux'
// import {bindActionCreators} from 'redux'
// import withRedux from 'next-redux-wrapper'
import { logInUser } from '../store'
class Home extends React.Component {
static async getInitialProps({ isLoggedIn }) {
return { isLoggedIn }
}
render() {
const { isLoggedIn } = this.props
return (
<div>
{console.log("isLoggedIn ", isLoggedIn)}
<Head title = 'Home' />
<HomeLayout isLoggedIn = { isLoggedIn }/>
</div>
)
}
}
export default connect(state => state)(Home);
And this is my pages/_app
import React from 'react'
import { Provider } from 'react-redux'
import App from 'next/app'
import withRedux from 'next-redux-wrapper'
import { initializeStore } from '../store'
export default withRedux(initializeStore)(
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
return {
pageProps: Component.getInitialProps
? await Component.getInitialProps(ctx)
: {}
}
}
render() {
const { Component, pageProps, store } = this.props
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
)
}
}
)
Any help
Upvotes: 7
Views: 11381
Reputation: 419
The reason that this is happening because the page that you're rendering is most probably statically generated. In React when you use ReactDOM.rehydrate this is generally what would happen and the best way is to use ReactDOM.render.
However with Nextjs either with Server-Side Rendering or Static Generation renders the entire HTML on the server or is stored on the server respectively. So when you try to render a component in any way such that the component is rendered based on the client this will pop up.
To get rid of this you can use ClientOnly wrapper component that will wrap anything that needs to be done on client-side.
import { useEffect, useState } from 'react';
interface Props {
children: React.ReactNode;
}
const ClientOnly: React.FC<Props> = ({ children, ...delegated }) => {
const [hasMounted, setHasMounted] = useState(false);
useEffect(() => {
setHasMounted(true);
}, []);
if (!hasMounted) {
return null;
}
return <div {...delegated}>{children}</div>;
};
export default ClientOnly;
Here are some resources about:
So all you have to do is wrap the component that is being client-side in the following way:
// below statement is dependent on the client but the page is static
const isDesktopCommonOrAbove = useMediaQuery({ minWidth: 1366 });
/* ...other stuff... */
// Returned JSX
<div>
<ClientOnly>
{isDesktopCommonOrAbove ? <div className={styles.board} /> : null}
</ClientOnly>
</div>
Upvotes: 16
Reputation: 9
Most of the time, it is due to the missing closing tag/brackets.
On nextJS, if you are using <style jsx>
then it is possible that some of your class didn't got wrapped under properly with brackets or a property missed semicolon.
e.g. the below code is going to give you the same warning.
Incorrect:
<style jsx>`{ // missing closing bracket
div {
background: #fff;
}`</style>
Correct:
<style jsx>`{
`div {
background: #fff;
}
}`</style>
Please look in the imported dependencies/components of your target component, you may be having a similar issue.
Upvotes: 0