akiran / react-slick

React carousel component
http://react-slick.neostack.com/
MIT License
11.78k stars 2.11k forks source link

Issue related to passing a ref prop (property 'slider' does not exist on type 'xyz') #1459

Closed ummahusla closed 5 years ago

ummahusla commented 5 years ago

So I've been trying to pass refs to the slider component and yet had no luck. I found a similar issue #1261 which lead me to this file and with the code example

https://github.com/akiran/react-slick/blob/c8d24263517273ae86b982cf783cd4e05ec0be08/examples/AutoPlayMethods.js#L28

This is how my component looks like

<Slider
    ref={slider => (this.slider = slider)}
    {...carouselSettings}
    className={fade ? 'slick-fade' : null}
>
    {children}
</Slider>

and here is the issue I'm having

ERROR in [at-loader] ./src/components/molecules/Carousel/index.tsx:53:38 
TS2339: Property 'slider' does not exist on type 'Carousel'.
ummahusla commented 5 years ago

Sorted it by slider: ISlider; and binding this.slider = React.createRef(); in the constructor. Then I just passed ref={this.slider} to the slider component as a prop. To pass the typescript issue, I've initially assigned slider: any, but then replaced it with an empty interface and started digging around the props it takes.

class Carousel extends Component<ICarouselProps, ICarouselState> {
    slider: ISlider;

    constructor(props) {

        ....

        this.slider = React.createRef();
    }

    ...

    render() {

        ...

        return (
            <Slider
                ref={this.slider}
                ...
            >
                {children}
            </Slider>
        );
    }
}
mnemanja commented 5 years ago

Hi @ummahusla , can you please tell me where did you get the ISlider from?

ummahusla commented 5 years ago

@mnemanja I've just created an empty interface interface ISlider {} or you could you use slider: any or something like this.

katia-aa commented 4 years ago

This is great! thanks a lot. You can also achieve the same thing with Function Components and Hooks:

import React from 'react'
import Slider from 'react-slick'

export const PreviousNextMethods = () => {
  const slider = React.useRef<Slider>(null)

  const settings = {
    infinite: true,
    speed: 500,
    slidesToShow: 1,
    slidesToScroll: 1,
  }

  return (
    <div>
      <h2>Previous and Next methods</h2>
      <Slider ref={slider} {...settings}>
        <div key={1}>
          <h3>1</h3>
        </div>
        <div key={2}>
          <h3>2</h3>
        </div>
        <div key={3}>
          <h3>3</h3>
        </div>
        <div key={4}>
          <h3>4</h3>
        </div>
        <div key={5}>
          <h3>5</h3>
        </div>
        <div key={6}>
          <h3>6</h3>
        </div>
      </Slider>
      <div style={{ textAlign: 'center' }}>
        <button className="button" onClick={() => slider?.current?.slickPrev()}>
          Previous
        </button>
        <button className="button" onClick={() => slider?.current?.slickNext()}>
          Next
        </button>
      </div>
    </div>
  )
}
OlivierDijkstra commented 3 years ago

This is great! thanks a lot. You can also achieve the same thing with Function Components and Hooks:

import React from 'react'
import Slider from 'react-slick'

export const PreviousNextMethods = () => {
  const slider = React.useRef<Slider>(null)

  const settings = {
    infinite: true,
    speed: 500,
    slidesToShow: 1,
    slidesToScroll: 1,
  }

  return (
    <div>
      <h2>Previous and Next methods</h2>
      <Slider ref={slider} {...settings}>
        <div key={1}>
          <h3>1</h3>
        </div>
        <div key={2}>
          <h3>2</h3>
        </div>
        <div key={3}>
          <h3>3</h3>
        </div>
        <div key={4}>
          <h3>4</h3>
        </div>
        <div key={5}>
          <h3>5</h3>
        </div>
        <div key={6}>
          <h3>6</h3>
        </div>
      </Slider>
      <div style={{ textAlign: 'center' }}>
        <button className="button" onClick={() => slider?.current?.slickPrev()}>
          Previous
        </button>
        <button className="button" onClick={() => slider?.current?.slickNext()}>
          Next
        </button>
      </div>
    </div>
  )
}

This doesn't seem to be working (anymore?) ref only contains a current object with a retry() method inside so calling any other function errors out. Tried all versions from 0.27.8 to 0.27.14.

opassion commented 2 years ago

@OlivierDijkstra Do you have any solution for this problem?

Shashank729 commented 3 months ago

This is great! thanks a lot. You can also achieve the same thing with Function Components and Hooks:

import React from 'react'
import Slider from 'react-slick'

export const PreviousNextMethods = () => {
  const slider = React.useRef<Slider>(null)

  const settings = {
    infinite: true,
    speed: 500,
    slidesToShow: 1,
    slidesToScroll: 1,
  }

  return (
    <div>
      <h2>Previous and Next methods</h2>
      <Slider ref={slider} {...settings}>
        <div key={1}>
          <h3>1</h3>
        </div>
        <div key={2}>
          <h3>2</h3>
        </div>
        <div key={3}>
          <h3>3</h3>
        </div>
        <div key={4}>
          <h3>4</h3>
        </div>
        <div key={5}>
          <h3>5</h3>
        </div>
        <div key={6}>
          <h3>6</h3>
        </div>
      </Slider>
      <div style={{ textAlign: 'center' }}>
        <button className="button" onClick={() => slider?.current?.slickPrev()}>
          Previous
        </button>
        <button className="button" onClick={() => slider?.current?.slickNext()}>
          Next
        </button>
      </div>
    </div>
  )
}

This is working for me, thanks a ton!