1

I want to add a Like button to my elements that I add through a forEach creating elements from an API call. So I imported a Like Button I made as a component and tried adding it to the card like this:

import LikeBtn from "./LikeBtn/LikeBtn";      

const likeBtn = document.createElement("span");
likeBtn.className = "imgcards__like-btn";
likeBtn.innerHTML = LikeBtn;

but it just comes out like this: result

LikeBtn component and rest of code for reference:

import React from "react";
import { AiFillHeart, AiOutlineHeart } from "react-icons/ai";

const LikeBtn = () => {
  let liked = this.props.liked || false;
  let count = this.props.count || true;
  let color = "lightcoral";

  if (liked) {
    return (
      <span
        class="likebtn__icon"
        style={{ color: color }}
        onClick={this.onClick}
      >
        <AiFillHeart />
        {count ? count : ""}
      </span>
    );
  } else {
    return (
      <span class="likebtn__icon" onClick={this.onClick}>
        <AiOutlineHeart />
        {count ? count : ""}
      </span>
    );
  }
};

export default LikeBtn;

import React from "react";
import "./ImageCards.css";
import LikeBtn from "./LikeBtn/LikeBtn";

function populateList(items) {
  items.forEach((item) => addItem(item));
}

function addItem(item) {
  const card = document.createElement("div");
  card.className = "imgcards__card";

  const cardContent = document.createElement("div");
  cardContent.className = "imgcards__card-content";

  const title = document.createElement("h1");
  title.className = "imgcards__title";
  title.innerHTML = item.title;

  const date = document.createElement("p");
  date.className = "imgcards__date";
  date.innerHTML = item.date;

  const image = document.createElement("img");
  image.className = "imgcards__image";
  image.src = item.hdurl;

  const likeBtn = document.createElement("span");
  likeBtn.className = "imgcards__like-btn";
  likeBtn.innerHTML = LikeBtn;

  cardContent.appendChild(title);
  cardContent.appendChild(date);
  cardContent.appendChild(image);
  cardContent.appendChild(likeBtn);

  card.appendChild(cardContent);

  document.getElementById("imgcards__cards-container").appendChild(card);
}

export default class ImageCards extends React.Component {
  async componentDidMount() {
    fetch(
      "https://api.nasa.gov/planetary/apod?count=20&api_key=lwtGe8ifpAENLITuYZ0b1gqxkdhZux9u2OdvlfB4",
      {
        method: "GET",
        headers: {
          "content-type": "application/json",
        },
      }
    )
      .then((response) => response.json())
      .then((data) => populateList(data));
  }

  render() {
    return (
      <div className="imgcards">
        <div
          className="imgcards__cards-container"
          id="imgcards__cards-container"
        ></div>
      </div>
    );
  }
}

This was my best idea for adding a like button that's responsive for each item, so other than my issue if you have a better way of doing it pls let me know. Thank you!

2
  • You should not be doing direct DOM manipulation for simply rendering elements when using React. No offense, but I think you should read through their tutorial. Commented Jan 19, 2022 at 0:38
  • Don't think there is anything offensive about it... thanks. Commented Jan 19, 2022 at 1:25

1 Answer 1

1

Avoid direct DOM manipulation as Chris stated. Regarding your case, It's better to use .map() on the items list. I wrote a quick sample based on your API request that you can start working with. See below:

    import React, {useState, useEffect} from "react";
    import "./style.css";
    
    export default function App() {
      const [data, setData] = useState([])
    
      useEffect(() => {
        fetch(
          "https://api.nasa.gov/planetary/apod?count=20&api_key=lwtGe8ifpAENLITuYZ0b1gqxkdhZux9u2OdvlfB4",
          {
            method: "GET",
            headers: {
              "content-type": "application/json",
            },
          }
        )
          .then((response) => response.json())
          .then((data) => setData(data));
      }, [])
    
      return (
        <div>
        {data.map((item, index) => (
    
          <div className="imgcards__title"> 
          {
         <li>{item.title}  {item.date}</li>
    }
        </div>
       
        ))
      }
        </div>
       
      );

}

You can also add the like button that you mentioned with the other html elements inside the .map() scope and apply whatever logic you wish to add using onClick() or other functionalities. I recommend reading the React documentation on how to use the map function with list to display data, here. Edit: don't forget add a key to each child as well as each element inside children.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.