yaodingyd / react-flickity-component

A React.js component for using @desandro's Flickity
314 stars 51 forks source link

Safari - Render carousel dynamically #36

Closed csantos1113 closed 7 months ago

csantos1113 commented 6 years ago

I'm trying to render this carousel component on Small viewports, and a plain list in other viewports. I'm using window.matchMedia to render one or the other component

import React, { PureComponent } from "react";
import { render } from "react-dom";
import Flickity from "react-flickity-component";

const flickityOptions = {
  initialIndex: 1,
  pageDots: false
};
const smMedia = window.matchMedia("(max-width: 650px) and (min-width: 0px)");

class Carousel extends PureComponent {
  constructor() {
    super();
    this.state = {
      carousel: false
    };
  }

  componentDidMount() {
    smMedia.addListener(this.onSmall);
    smMedia.addListener(x => console.log("Fired?", x.matches));
  }

  onSmall = ({ matches }) => {
    this.setState({
      carousel: matches ? flickityOptions : false
    });
  };

  render() {
    const { carousel } = this.state;

    if (carousel) {
      return (
        <Flickity options={carousel}>
          <img src="http://via.placeholder.com/50x50" />
          <img src="http://via.placeholder.com/50x50" />
          <img src="http://via.placeholder.com/50x50" />
          <img src="http://via.placeholder.com/50x50" />
          <img src="http://via.placeholder.com/50x50" />
        </Flickity>
      );
    }

    return (
      <div style={{ border: "1px solid", padding: 10 }}>
        Plain List No {this.props.number}
      </div>
    );
  }
}

const Wrapper = () => {
  return (
    <div>
      <Carousel number={1} />
      <Carousel number={2} />
    </div>
  );
};

render(<Wrapper />, document.getElementById("root"));

in Safari only - The second list is not able to change to the carousel, without any errors anywhere.

See this live example: https://codesandbox.io/s/5409mo1qkx

yaodingyd commented 6 years ago

It doesn't looks like a bug with react-flickity-component, more like Safari is doing weird stuff. I never get Fired? true in my console log.

csantos1113 commented 6 years ago

That's the thing, something is happening behind scenes in the Flickity library that is crashing the matchMedia listeners chain to be called. And only on Safari. This is the strangest error that I have seen.

You can get Fired? true if you run the example in any other browser different than Safari.

btw, just for testing, you can change carousel: matches ? flickityOptions : false ===> carousel: flickityOptions, and you will be able to see Fired? true in your console log

yaodingyd commented 7 months ago

looks like safari fix the matchMedia issue https://caniuse.com/?search=matchmedia