yaodingyd / react-flickity-component

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

Using with flickity-as-nav-for - Typescript #121

Closed SergioTabarini closed 5 months ago

SergioTabarini commented 3 years ago

Hello, does someone know how to implement the flickity-as-nav-for using this react-flickity-component in NextJs and using typescript?

Right now Im using these options for the main and the nav carousel, Im a little bit lost on how this should work, any advice? thanks.

const flickityOptions = {
  lazyLoad: true,
  prevNextButtons: true,
  pageDots: false,
  cellAlign: 'left',
  contain: true,
  arrowShape: { 
    x0: 10,
    x1: 60, y1: 50,
    x2: 75, y2: 40,
    x3: 35
  }
}
const flickityNavOptions = {
  asNavFor: '.carousel-main',
  pageDots: false,
  contain: true,
}
ivanlucci1 commented 3 years ago

Hello Sergio, I was passing through the same problem here. I found a solution using Flickity's API and Events, as described on the end of the README.md file. Here is an adaptation I made using 2 Flickity instances:

class Carousel extends React.Component {

  componentDidMount = () => {
    // You can register events in componentDidMount hook
    this.flkty.on('settle', () => {
      console.log(`current index is ${this.flkty.selectedIndex}`)
    })
  }

  myCustomNext = () => {
    // You can use Flickity API
    this.flktyA.next()
    this.flktyB.next()
  }

  render() {
    return (
      <Flickity flickityRef={c => this.flktyA = c}>
        <img src="/images/placeholder.png"/>
        <img src="/images/placeholder.png"/>
        <img src="/images/placeholder.png"/>
      </Flickity>
      <Flickity flickityRef={c => this.flktyB = c}>
        <img src="/images/placeholder.png"/>
        <img src="/images/placeholder.png"/>
        <img src="/images/placeholder.png"/>
      </Flickity>
      <Button onClick={myCustomNext}>My custom next button</Button>
    )
  }
}

Hope it helps =D

DavidSubiros commented 1 year ago

Hi, I'm using this approach, but with functional components, and I'm using a reference to the flickity component. Unfortunately, it seems I can't register callbacks with the flkty.on(...) approach. Here is the relevant part of my code:

const PartCarousel = ({pvr, token, role}: PartCarouselProps): JSX.Element => {
    const ref = useRef<Flickity|null>(null)
    const refAux = useRef<Flickity|null>(null)

    useEffect(() => {
        if(!ref.current) {
            console.log("failed to register cbk as ref is not set")
            return
        }
        console.log("ref current")
        console.log(ref.current)
        ref.current.on('settle', () => { // TODO this does not work
            console.log(`current index is ${ref.current?.selectedIndex}`)
        })
    },[]);

    ...
        return(
        <div>
        <Flickity
            ref={ref}
            ...
        )
    }       

I get the following typsecript error:

ref.current.on is not a function
TypeError: ref.current.on is not a function
    at http://localhost:3000/main.390418308a6d040892dc.hot-update.js:68:17
    ...

If I remove the callback registering ref.current.on(...) then I don't see the error and the carousel works (but without the callback, of course)

Does anyone have this working with typescript functional components, or an idea of how to fix the types? (I'm quite new at front end and react, my expertise is back end)

yaodingyd commented 5 months ago

@DavidSubiros you need to use flickityRef={c => ref.currrent = c} function to assign ref for flickity instance (also see example in readme). Using ref prop would not work