简体   繁体   中英

How can i add a favorite item to a newly created list

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;

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;

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}
    />
  ))
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM