yaodingyd / react-flickity-component

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

flkty.resize is not a function #62

Closed gfrcsd closed 5 years ago

gfrcsd commented 5 years ago

Hi!

I am using the component inside of a modal, everything is working, arrows and dots are here but all the images are stacked on top of each other. If I resize the window it fixes itself. Following the API on flickity's website, I read that I need to use resize() when I reveal the slider

Function run onClick

function openModal(){
    var carousel = document.querySelector('.carousel');
    var flkty = new Flickity( carousel );
    document.getElementById('modal').style.display = 'flex';
    flkty.resize();
}

Options

const flickityOptions = {
    initialIndex: 0,
    imagesLoaded: true
}

Slider

<Flickity 
  id='test'
  className={'carousel'} // default ''
  elementType={'div'} // default 'div'
  options={flickityOptions} // takes flickity options {}
  disableImagesLoaded={false} // default false
  reloadOnUpdate={true}// default false
>
  {post.frontmatter.images.map(({ publicURL, id }) => (
  <CarouselCell key={id} id={id}>
    <img src={publicURL} alt="" />
  </CarouselCell>
  ))}
</Flickity>

I get flkty.resize is not a function.

I am no JavaScript expert and I am new to React so I apologies in advance if this is a stupid question

yaodingyd commented 5 years ago

If you want to access Flickity instance, there is the guide: https://github.com/theolampert/react-flickity-component#use-flickitys-api-and-events

gfrcsd commented 5 years ago

I think it's due to my limited knowledge of the different syntax in use in React, but I can't seem to see a similar structure in my component and I am struggling to implement the example in the link above

Original Code

export default () => {  
    return (
        <Layout>
                <Modal id="modal">
                    <div className="modal-background"></div>
                    <SliderContainer>
                        <Flickity 
                        id='test'
                        className={'carousel'} // default ''
                        elementType={'div'} // default 'div'
                        options={flickityOptions} // takes flickity options {}
                        disableImagesLoaded={false} // default false
                        reloadOnUpdate={true}// default false
                        >
                        {post.frontmatter.images.map(({ publicURL, id }) => (
                        <CarouselCell key={id} id={id}>
                            <img src={publicURL} alt="" />
                        </CarouselCell>
                        ))}
                        </Flickity>
                    </SliderContainer>
                    <button className="modal-close is-large" onClick={closeModal} aria-label="close"></button>
                </Modal>
        </Layout>
    )
}

Failed implementation attempt

class Carousel extends React.Component {

    openModal = () => {
        document.getElementById('modal').style.display = 'flex';
        this.flkty.resize();
    }

    closeModal = () => {
        document.getElementById('modal').style.display = 'none';
    }

    render() {
        return (
        <Layout>
                <Modal id="modal">
                    <div className="modal-background"></div>
                    <SliderContainer>
                        <Flickity
                            flickityRef={c => this.flkty = c}
                            id='test'
                            className={'carousel'} // default ''
                            elementType={'div'} // default 'div'
                            options={flickityOptions} // takes flickity options {}
                            disableImagesLoaded={false} // default false
                            reloadOnUpdate={true}// default false
                        >
                            {post.frontmatter.images.map(({ publicURL, id }) => (
                            <CarouselCell key={id} id={id}>
                                <img src={publicURL} alt="" />
                            </CarouselCell>
                            ))}
                        </Flickity>
                    </SliderContainer>
                    <button className="modal-close is-large" onClick={closeModal} aria-label="close"></button>
                </Modal>
        </Layout>
    )
    }
}

Errors

  47:7   warning  'Carousel' is defined but never used  no-unused-vars
  70:57  error    'openModal' is not defined            no-undef
  95:71  error    'closeModal' is not defined           no-undef
devndive commented 5 years ago

What you can do, is to dispatch a resize event when opening / showing your modal dialog.

openModal = () => {
    document.getElementById('modal').style.display = 'flex';
    window.dispatchEvent(new Event('resize'));
}

Source - https://stackoverflow.com/a/1818513

You have to test this solution with the browsers you are using. In the linked post there is another solution for IE if you need that.

yaodingyd commented 5 years ago

Again, you need to use ref to use flickity APIs.

<Flickity 
  id='test'
  className={'carousel'} // default ''
  elementType={'div'} // default 'div'
  options={flickityOptions} // takes flickity options {}
  disableImagesLoaded={false} // default false
  reloadOnUpdate={true}// default false
  flickityRef={c => this.flkty = c}
>

Then you can use this.flkty to call APIs. Check https://reactjs.org/docs/refs-and-the-dom.html to learn about refs.