Alamin
Alamin

Reputation: 2165

TypeError: Cannot set property 'innerHTML' of null

I'm trying to make a testimonial with js DOM, but i have an error with innerHtml.

I have trying following code::

import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faQuoteLeft, faQuoteRight } from "@fortawesome/free-solid-svg-icons";

const testimonials = [
  {
    name: "Miyah Myles",
    position: "Marketing",
    photo: "https://randomuser.me/api/portraits/women/46.jpg",
    text: `It is a long established fact that a reader will be distracted by
        the readable content of a page when looking at its layout. The point
        of using Lorem Ipsum is that it has a more-or-less normal
        distribution of letters, as opposed to using 'Content here, content
        here', making it look like readable English. Many desktop publishing
        packages and web page editors now use Lorem Ipsum as their default
        model text, and a search`,
  },
  {
    name: "Sheikh",
    position: "Marketing",
    photo: "https://randomuser.me/api/portraits/women/46.jpg",
    text: `It is a long established fact that a reader will be distracted by
        the readable content of a page when looking at its layout. The point
        of using Lorem Ipsum is that it has a more-or-less normal
        distribution of letters, as opposed to using 'Content here, content
        here', making it look like readable English. Many desktop publishing
        packages and web page editors now use Lorem Ipsum as their default
        model text, and a search`,
  },
];

const testimonialContainer = document.querySelector(".testimonials-container");
const testimonial = document.querySelector(".testimonial");
const userImage = document.querySelector(".user-image");
const username = document.querySelector(".username");
const role = document.querySelector(".role");

let idx = 1;
function updateTestimonial() {
  const { name, position, photo, text } = testimonials[idx];

  testimonial.innerHTML = text;
  userImage.src = photo;
  username.innerHTML = name;
  role.innerHTML = position;

  idx++;

  if (idx > testimonials.length - 1) {
    idx = 0;
  }
}
setInterval(updateTestimonial, 10000);

const Testimonial = () => {
  return (
    <div className="container mt-5 custom_testi">
      <div className="row">
        <div className="testimonial-container">
          <div className="progress-bar"></div>
          <span>
            <FontAwesomeIcon
              icon={faQuoteRight}
              className="fa-quote fa-quote-right"
            />
          </span>
          <span>
            <FontAwesomeIcon
              icon={faQuoteLeft}
              className="fa-quote fa-quote-left"
            />
          </span>

          <p className="testimonial">
            It is a long established fact that a reader will be distracted by
            the readable content of a page when looking at its layout. The point
            of using Lorem Ipsum is that it has a more-or-less normal
            distribution of letters, as opposed to using 'Content here, content
            here', making it look like readable English. Many desktop publishing
            packages and web page editors now use Lorem Ipsum as their default
            model text, and a search
          </p>
          <div className="user">
            <img
              src="https://randomuser.me/api/portraits/women/46.jpg"
              alt=""
              className="user-image"
            />
            <div className="user-details">
              <h4 className="username">Miyah Myles</h4>
              <p className="role">Marketing</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Testimonial;

first one is static from my Testimonial function, after that i have dynamic data from testimonials function but when i want to show output then show me error like this:

TypeError: Cannot set property 'innerHTML' of null

I have tried many time but show me same error.

Any suggestion please.

Upvotes: 0

Views: 234

Answers (1)

codemonkey
codemonkey

Reputation: 7905

If you want to do the way you tried, I suggest using useRef(). It's a way to control your html elements in JSX. The idea is similar to yours, but one that actually works:

  const testimonialElem = useRef();
  useEffect(() => {
    let idx = 1;
    function updateTestimonial() {
      const { name, position, photo, text } = testimonials[idx];

      testimonialElem.current.innerHTML = text;
      idx++;

      if (idx > testimonials.length - 1) {
        idx = 0;
      }
    }
    setInterval(updateTestimonial, 3000);
  }, []);

I have only Refed one element, the p tag with the main text of the testimonial, but you can easily create separate refs for the rest of the dynamic components. Here is a Sandbox: https://codesandbox.io/s/old-monad-ojxn5?file=/src/App.js

Please note that given that you use React, taking advantage of state variables should be considered.

Upvotes: 1

Related Questions