Home > front end >  How can i add a favorite item to a newly created list
How can i add a favorite item to a newly created list

Time:02-26

when someone clicks an item i want to store that clicked item in my likedjokes array. i mean empty state array. i tried this solution but instead of showing a new post it just shows post.id.

basically this is the result: image

and this is what i want image

Home.js

import React, { useState, useEffect } from "react";
import { getDocs, collection, deleteDoc, doc } from "firebase/firestore";
import { db, auth } from "../../firebase";
import { Link } from "react-router-dom";
import Sidebar from "../Sidebar/Sidebar";
import "./Home.css";
import PostList from "./PostList";

const Home = ({ isAuth, setIsAuth }) => {
  const [postLists, setPostList] = useState([]);
  const postsCollectionRef = collection(db, "posts");
  const [likedJokes, setLikedJokes] = useState([]);

  useEffect(() => {
    const getPosts = async () => {
      const data = await getDocs(postsCollectionRef);
      setPostList(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
    };

    getPosts();
  }, []);

  const addFavorite = (postLists) => {
    setLikedJokes((prevlikedJokes) => [...prevlikedJokes, postLists]);
    console.log(postLists);
  };

  return (
    <div className="containers">
      <div className="sidebar">
        <Sidebar isAuth={isAuth} setIsAuth={setIsAuth} />
        <div className="centered">
          <div className="bordered">
            <button id="ado">
              <Link to="/createpost">  Add API</Link>
            </button>
          </div>

          <div className="new-container">
            {postLists?.map((post) => {
              return (
                <>
                  <PostList
                    linkin={post.linkin}
                    id={post.id}
                    title={post.title}
                    imageURL={post.imageURL}
                    photoURL={post.photoURL}
                    name={post.name}
                    addFavorite={addFavorite}
                    likedJokes={likedJokes}
                    setLikedJokes={setLikedJokes}
                  />
                </>
              );
            })}
          </div>
        </div>
        {likedJokes}
      </div>
    </div>
  );
};

export default Home;

PostList.js. im using firebase to get documents btw.

import React from "react";

const PostList = ({
  linkin,
  title,
  post,
  index,
  imageURL,
  photoURL,
  name,
  likeJoke,
  likedJokes,
  id,
  setLikedJokes,
  addFavorite,
}) => {
  return (
    <>
      <div>
        <div className="post" key={id}>
          <div className="postimage">
            <div className="del"></div>

            <div className="images">
              <a href={linkin}>
                <p className="ss">{title}</p>

                <img src={imageURL} id="img-photo" />
              </a>
              <div className="uploader">
                <img src={photoURL} />

                <p>by {name}</p>
                {likedJokes}
              </div>
              <div className="butons">
                <button onClick={() => addFavorite(id)} id="favori">
                   
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default PostList;

CodePudding user response:

The likedJokes array is an array of post ids updated from the button

<button onClick={() => addFavorite(id)} id="favori">
   
</button>

You can filter the postLists array for those having post ids in the likedJokes array, then map these to PostList components (assumes you are reusing the same component, looks like it in the expected screencap).

{postLists
  .filter(post => likedJokes.includes(post.id))
  .map((post) => (
    <PostList
      key={post.id}
      linkin={post.linkin}
      id={post.id}
      title={post.title}
      imageURL={post.imageURL}
      photoURL={post.photoURL}
      name={post.name}
      addFavorite={addFavorite}
      likedJokes={likedJokes}
      setLikedJokes={setLikedJokes}
    />
  ))
}

CodePudding user response:

Here is a way you can refactor what you had to accomplish what you want. If you want to save to the database, in the add favorite you could make a DB call. I would suggest making a component for the liked jokes. Suggestion when you are using every property on an object pass in the full object instead. When you get to many props it should be a warning sign that something is wrong.

import React, { useState, useEffect } from 'react';
import { getDocs, collection, deleteDoc, doc } from 'firebase/firestore';
import { db, auth } from '../../firebase';
import { Link } from 'react-router-dom';
import Sidebar from '../Sidebar/Sidebar';
import './Home.css';
import PostList from './PostList';

const Home = ({ isAuth, setIsAuth }) => {
    const postsCollectionRef = collection(db, 'posts');
    const [postLists, setPostList] = useState([]);
    const [likedJokes, setLikedJokes] = useState([]);

    useEffect(() => {
        const getPosts = async () => {
            const data = await getDocs(postsCollectionRef);
            setPostList(
                data.docs.map((doc) => ({ ...doc.data(), id: doc.id }))
            );
        };

        getPosts();
    }, []);

    const addFavorite = (likedJoke) => {
        setLikedJokes((prevlikedJokes) => [...prevlikedJokes, likedJoke]);
    };

    return (
        <div className="containers">
            <div className="sidebar">
                <Sidebar isAuth={isAuth} setIsAuth={setIsAuth} />
                <div className="centered">
                    <div className="bordered">
                        <button id="ado">
                            <Link to="/createpost">  Add API</Link>
                        </button>
                    </div>
                    <div className="new-container">
                        {postLists.map((post) => <Post post={post} addFavorite={addFavorite} key={post.id} />)}
                    </div>
                </div>
                // TODO: Maybe make a LikedJoke Component
                {likedJokes.map(post => <Post post={post} key={post.id} />)}
            </div>
        </div>
    );
};

export default Home;

const Post = ({ post, addFavorite }) => {
    const { linkin, title, imageURL, photoURL, name } = post;
    return (
        <>
            <div className="post">
                <div className="postimage">
                    <div className="del"></div>
                    <div className="images">
                        <a href={linkin}>
                            <p className="ss">{title}</p>
                            <img src={imageURL} id="img-photo" />
                        </a>
                        <div className="uploader">
                            <img src={photoURL} />
                            <p>by {name}</p>
                        </div>
                        {addFavorite && (
                            <div className="butons">
                                <button onClick={() => addFavorite(post)} id="favori"> </button>
                            </div>
                        )}
                    </div>
                </div>
            </div>
        </>
    );
};

export default PostList;
  • Related