`this.setState is not a function` error occured when I used slick slider library

I’m making slider by using slick-slider library. And I’m making a function that shows the current page number like 1/3. I referred to the code to implement this function. But this.setState is not a function occured. I’ve referred to another article, but it’s not solved. I looked it up and it seems like the grammar of typescript, but I don’t know how to solve it. I’d appreciate it if you let me know.

import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import styled from "styled-components";

const array = [
  {
    id: 1,
    text: "page1"
  },
  {
    id: 2,
    text: "page2"
  },
  {
    id: 3,
    text: "page3"
  }
];

export default function SimpleSlider() {
  
  // this is the part where error occured
  state = { currentSlide: 0 };

  handleAfterChange = (index) => {
    console.log("after change", index);
    this.setState({
      currentSlide: index
    });
  };

  const settings = {
    infinite: true,
    speed: 500,
    slidesToShow: 1,
    slidesToScroll: 1,
    beforeChange: function (currentSlide, nextSlide) {
      console.log("before change", currentSlide, nextSlide);
    },
    afterChange: this.handleAfterChange
  };

  return (
    <Wrap>
      <Slider {...settings}>
        {array.map((element) => {
          return (
            <div
              className={`sliderWrap ${
                element.id === 1 ? "num1" : element.id === 2 ? "num2" : "num3"
              }`}
              key={element.id}
            >
              <h3>{element.text}</h3>
            </div>
          );
        })}
      </Slider>
      <div>
        {" "}
        {this.state.currentSlide + 1} / {array.length}{" "}
      </div>
    </Wrap>
  );
}

const Wrap = styled.div`
  .sliderWrap.num1 {
    background-image: url("https://shopimg.kakaofriendsgolf.com/live/images/2023/1/2/10/117580_1672622112593.png");
    background-color: #fff3dd;
    height: 740px;
    background-position: center;
    background-repeat: no-repeat;
    background-size: auto 740px;
    display: flex !important;
    align-items: center;
  }

  .sliderWrap.num2 {
    background-image: url("https://shopimg.kakaofriendsgolf.com/live/images/2022/12/19/10/922469_1671412154586.png");
    background-color: #f8d58a;
    height: 740px;
    background-position: center;
    background-repeat: no-repeat;
    background-size: auto 740px;
    display: flex !important;
    align-items: center;
  }

  .sliderWrap.num3 {
    background-image: url("https://shopimg.kakaofriendsgolf.com/live/images/2022/11/16/13/853128_1668573855540.png");
    background-color: #a9d7f1;
    height: 740px;
    background-position: center;
    background-repeat: no-repeat;
    background-size: auto 740px;
    display: flex !important;
    align-items: center;
  }
`;

this is my code in codesandbox

I reffered this code

>Solution :

The code you’ve written is a mix of what would be needed for a class component, and a function component. The combination does not work. If you want it to be a function component, you need to use the useState hook to do your state, and not reference this. Also, you need to use const or let when declaring your variables:

import { useState } from 'react';

export default function SimpleSlider() {
  const [currentSlide, setCurrentSlide] = useState(0);

  const handleAfterChange = (index) => {
    console.log("after change", index);
    setCurrentSlide(index);
  };

  const settings = {
    infinite: true,
    speed: 500,
    slidesToShow: 1,
    slidesToScroll: 1,
    beforeChange: function (currentSlide, nextSlide) {
      console.log("before change", currentSlide, nextSlide);
    },
    afterChange: handleAfterChange
  };

  return (
    <Wrap>
      <Slider {...settings}>
        {array.map((element) => {
          return (
            <div
              className={`sliderWrap ${
                element.id === 1 ? "num1" : element.id === 2 ? "num2" : "num3"
              }`}
              key={element.id}
            >
              <h3>{element.text}</h3>
            </div>
          );
        })}
      </Slider>
      <div>
        {" "}
        {currentSlide + 1} / {array.length}{" "}
      </div>
    </Wrap>
  );
}

If you want this to be a class component, then you need a class that extends from React.Component, and you need to move some code into the render method:

import { Component } from "react";

export default class SimpleSlider extends Component {
  state = { currentSlide: 0 };

  handleAfterChange = (index) => {
    console.log("after change", index);
    this.setState({
      currentSlide: index,
    });
  };

  render() {
    const settings = {
      infinite: true,
      speed: 500,
      slidesToShow: 1,
      slidesToScroll: 1,
      beforeChange: function (currentSlide, nextSlide) {
        console.log("before change", currentSlide, nextSlide);
      },
      afterChange: this.handleAfterChange,
    };

    return (
      <Wrap>
        <Slider {...settings}>
          {array.map((element) => {
            return (
              <div
                className={`sliderWrap ${
                  element.id === 1 ? "num1" : element.id === 2 ? "num2" : "num3"
                }`}
                key={element.id}
              >
                <h3>{element.text}</h3>
              </div>
            );
          })}
        </Slider>
        <div>
          {" "}
          {this.state.currentSlide + 1} / {array.length}{" "}
        </div>
      </Wrap>
    );
  }
}

If you’re not sure which one to do, i recommend you do function components.

Leave a Reply