Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

`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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading