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.