Home > Back-end >  jest TypeError: Cannot read property 'createRef' of undefined
jest TypeError: Cannot read property 'createRef' of undefined

Time:05-07

ImageSlider.tsx

const ImageSlider = (props: INF_ImageSlider) => {
    const [idx, setIdx] = useState(0);
    const imgRef = React.createRef<HTMLImageElement>(); // <---- Error here
    // ...
}

ImageSlider.test.tsx

test('Slide between images', () => {
    render(
        <ImageSlider imgUrls={['./img1', './img2']} alt='' />
    )
    // ...
}

jest config

"jest": {
    "transform": {
      "^. \\.tsx?$": "ts-jest"
    },
    "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ]
  }

This component uses the createRef hook, but when I try to test it, it throw's the error TypeError: Cannot read property 'createRef' of undefined, how can I fix it?

CodePudding user response:

I've checked the documentation about using and creating ref's and so far I've seen that it can not take a value like you have it...

What you have

const imgRef = React.createRef<HTMLImageElement>(); 

I believe it's throwing an error because you are trying to squeeze in an image element.

From the documentation the way I see it is

const imgRef = React.createRef()

Here is how I would go about doing an image slideshow. I'm not too knowledgeable about Jest with react, but here is how I would go about it if I was using react.

Dependencies

React-slideshow-image

Installation Guide: Found Here

NPM

  • npm install react-slideshow-image -S
  • yarn add react-slideshow-image

import React, { Component } from "react";
import { Slide } from "react-slideshow-image";

**How to put this in a different js file and then import it into your

main App.js!**

export class Slideshows extends Component {
  constructor() {
    super();
    this.slideRef = React.createRef();
    this.previous = this.previous.bind(this);
    this.next = this.next.bind(this);
    this.state = {
      current: 0,
    };
  }

  previous() {
    this.slideRef.current.goBack();
  }

  next() {
    this.slideRef.current.goNext();
  }

  render() {
    const properties = {
      duration: 'time',
      autoplay: 'T/F',
      transitionDuration: 'time',
      arrows: 'True/False',
      infinite: 'True/False',
      easing: "Anytype of easing",
      indicators: (i) => <div className="indicators">{i   1}</div>,
    };
    const slideImages = [
      "https://images.unsplash.com/photo-1509721434272-b79147e0e708?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80",
      "https://images.unsplash.com/photo-1506710507565-203b9f24669b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1536&q=80",
      "https://images.unsplash.com/photo-1536987333706-fc9adfb10d91?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80",
      "https://images.unsplash.com/photo-1444525873963-75d329ef9e1b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80",
    ];
    return (
      <div className="SlideShow">
        <h3>Sliding W/ React</h3>
        <div className="slide-container">
          <Slide ref={this.slideRef} {...properties}>
            {slideImages.map((each, index) => (
              <div key={index} className="each-slide">
                <img className="imgname?" src={each} alt="alt-text" />
              </div>
            ))}
          </Slide>
        </div>

        <div className="slide-container buttons">
          <button onClick={this.previous} type="button">
            Previous
          </button>
          <button onClick={this.next} type="button">
            Forward
          </button>
        </div>
      </div>
    );
  }
}

How you incorporate it into your main app.js file


class App extends Component {
    constructor() {
        super();
        this.slideRef = React.createRef();
        this.previous = this.previous.bind(this);
        this.next = this.next.bind(this);
        this.state = {
            current: 0
        };
    }

    previous() {
        this.slideRef.current.goBack();
    }
    next() {
        this.slideRef.current.goNext();
    }

    render() {
        const properties = {
            duration:,
            autoplay:,
            transitionDuration:,
            arrows:,
            infinite:,
            easing:,
            indicators: (i) => <div className="indicator">{i   1}</div>
        };
        const slideImages = [
            "",
            "",
            "",
            "",
        ];
        return (
<div className="App">
        <h3>Sliding W/ react</h3>
        <div className="slide-container">
          <Slide ref={this.slideRef} {...properties}>
            {slideImages.map((each, index) => (
              <div key={index} className="each-slide">
                <img className="" src={each} alt="" />
              </div>
            ))}
          </Slide>
        </div>

        <div className="slide-container-btns">
          <button onClick={this.back} type="button">
            Previous
          </button>
          <button onClick={this.next} type="button">
            Foward
          </button>
        </div>
      </div>
    );
  }
}

export default App

CodePudding user response:

It is essential to tell the difference between class and functional components. Since you use a hook (fits only functional components) and use "createRef" (fits only class components), you should choose your preference.
Import useReact hook for a functional component.
OR
Create a state for a class component.

  • Related