-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SSR and responsive mode #1245
Comments
I am facing a similar issue with SSR. Were you able to find a fix? |
Is any solution to prevent this bug? Thank you. |
I don't know if is the best approach but I solved this problem by using dynamic import
|
I too am having this same issue. For now I have to use another plugin since it's mixing up the content for me |
+1 |
3 similar comments
+1 |
+1 |
+1 |
Thank you @davidsanchez96 |
+1 |
1 similar comment
+1 |
Following @davidsanchez96's lead, I still wanted the actual content to be rendered on both the server and the client, so this was my approach. import React, { Component } from 'react';
import dynamic from 'next/dynamic';
import classNames from 'classnames';
class Slider extends Component {
state = {
isServer: true
};
componentDidMount() {
this.setState((state) => state.isServer && { isServer: false });
}
render() {
const { settings, className, children } = this.props;
const SliderRendered = dynamic(import('react-slick'), {
ssr: this.state.isServer
});
return (
<SliderRendered className={classNames('Slider', className)} {...settings}>
{children}
</SliderRendered>
);
}
}
export default Slider; ...or with hooks: import React, { useState, useEffect } from 'react';
import dynamic from 'next/dynamic';
import classNames from 'classnames';
const Slider = ({ settings, className, children }) => {
const [isServer, setServerState] = useState(true);
const SliderRendered = dynamic(import('react-slick'), {
ssr: isServer
});
useEffect(() => void setServerState(false), []);
return (
<SliderRendered className={classNames('Slider', className)} {...settings}>
{children}
</SliderRendered>
);
};
export default Slider; |
This is my solution: import React, { PureComponent } from 'react';
import SlickSlider from 'react-slick';
class Slider extends PureComponent {
state = {
isClient: false
};
componentDidMount() {
this.setState((state) => { isClient: true });
}
render() {
const {
children,
responsive,
...rest
} = this.props;
const { isClient } = this.state;
return (
<SlickSlider
key={isClient ? 'client' : 'server'}
responsive={isClient ? responsive : null}
{...rest}
>
{children}
</SlickSlider>
);
}
}
export default Slider; |
Well, I have this bug but I don't want a state for this. |
@akiran any updates regarding this issue? |
@akiran any updates? |
Thanks for this solution @isBatak ! I can't quit figure out exactly in my head what happens here; the images are still being rendered on server-side but it works because .......? |
Hi, I had the same issue. The workaround works great. @silksil I think it works because when we use different keys react won't hydrate the state from the server but creates it from scratch on the client. Setting responsive to @akiran any hint how we can fix it? |
Hi @silksil, that trick is called two-pass rendering, you can find more info here https://reactjs.org/docs/react-dom.html#hydrate. In a nutshell, it will trigger second render on the client.
Overall, this problem can't be solved with JS because there is no window on server side and there is no way to detect window width. Only way to solve it is to generate pure CSS media queries and never touch the DOM structure. |
Any updates? |
@akiran any update on the issue ? |
Inspired by the @isBatak solution, mine is using react hooks: import { useState, useEffect } from 'react';
import SlickSlider from 'react-slick';
const Slider = ({ children, responsive, ...rest}) => {
const [isClient, setIsClient] = useState(false);
useEffect(() => {
setIsClient(true);
}, [])
return (
<SlickSlider
key={isClient ? 'client' : 'server'}
responsive={isClient ? responsive : null}
{...rest}
>
{children}
</SlickSlider>
);
}
export default Slider; |
If I use this for SSR, it gives me warning like these two
What is the solution for this warning? |
Hello, @rubenkuipers It'd be great if you advice me. |
If you are using next js then just use dynamic import for that component where you used react-slick or if you are not using ssr then just use lazyload component and suspension . |
Tried using dynamic import |
import Slider from "react-slick" use below example when you are importing your slider component to page |
There have same problem when use swiper/react in nextjs with responsive mode |
// component swiper
import { Swiper, SwiperSlide } from 'swiper/react';
import SwiperCore, { Navigation, Pagination } from 'swiper';
import 'swiper/swiper.min.css';
import 'swiper/components/pagination/pagination.min.css';
SwiperCore.use([Navigation, Pagination]);
<Swiper
navigation={{
nextEl: '.next',
prevEl: '.prev',
}}
breakpoints={{
1000: {
slidesPerView: 3,
},
0: {
slidesPerView: 1,
},
}}>
{data.map((item, index) => (
<SwiperSlide key={index}>
<article>
<img src={item.thumbnailUrl} />
<h2>{item.id}</h2>
</article>
</SwiperSlide>
))}
</Swiper>
//----------------------------------------------------
// index.js
const DynamicComponent = dynamic(() => import('../components/Swiper'), {
ssr: false,
});
export default function Home({ data }) {
return (
<div>
<DynamicComponent data={data} />
</div>
);
}
export async function getServerSideProps() {
const res = await fetch(
`https://jsonplaceholder.typicode.com/photos?_limit=10`
);
const data = await res.json();
return { props: { data } };
} |
@anettwu Thanks for the hint |
+1 |
next js 14 not working , facing hydration problems |
I spent a lot of time on this same issue, @leonace924. This is what I did (I'm not using Next.js!)
I hope this helps |
I already open this issue on the nextjs repo but it seems to be a problem with react-slick.
Describe the bug
When I use next.js with react-slick and responsive options, there is a bug during the rehydration phase, the src attribute of the images are mixed between the slides.
The error message is
Warning: Prop src did not match. Server: "http://via.placeholder.com/350x150?text=7" Client: "http://via.placeholder.com/350x150?text=8"
To Reproduce
I made an example from examples folder : https://github.com/padupuy/next.js/tree/feature/with-react-slick
The code is right here : https://github.com/padupuy/next.js/blob/feature/with-react-slick/examples/with-react-slick/pages/index.js
Expected behavior
The image sources must not be mixed
Screenshots
System information
The text was updated successfully, but these errors were encountered: