Passed-down props rendering undefined on first page load? - javascript

I have a site that is rendering cards of music artists then allowing the user to click on a button "View Ticket Activity" on each artist's card, which then allows more information to show up. Styled using Tailwind (the class names) and using react-router-v6.
I defined my artists state to successfully pull all the seeded artists from a rails DB and I output these artists all at once via a component called <ArtistsDisplay /> (which is routed to '/artists', where I pass down artists={artists} from the parent component <App />. In <ArtistsDisplay />, each artist maps out.
I have a separate component called <EachArtistCard /> that is routed (in <App />) to '/artists/:id' and is redirected there by a useNavigate() within <ArtistDisplay />. The problem there is that artist passes down from the parent <ArtistDisplay /> to the child <EachArtistCard /> and thisArtist=undefined on the first pass, which then breaks the map function within <EachArtistCard />. I'm defining it as thisArtist in place of artist within as a just in case to not have conflict name-wise with the const thisArtist = artists.find( (artist) => parseInt(id) === parseInt(artist.id) );
Within <ArtistsDisplay /> is my major issue. I've tried many re-writes (replacing the new component with an in-component modal, reconfiguring routes, etc) but fundamentally I need to understand why I have the thisArtist=undefined rendering issue. I'm not in strictMode (afaik) as I've seen the double-render-in-development posts so it's gotta be my error somewhere in my writing of this app.
ArtistsDisplay.js
function ArtistsDisplay({ artists, user, searchTerm, setSearchTerm }) {
let navigate = useNavigate();
return (
<div class='bg-base-900 py-6 sm:py-8 lg:py-12'>
<div class='form-control'>
<label class='flex input-group input-group-lg'>
<span>SEARCH</span>
<input
type='text'
onChange={(e) => setSearchTerm(e.target.value)}
placeholder='Search for your favorite artists here...just start typing'
class='input input-bordered w-full input-lg text-center'
/>
</label>
</div>
<div>
<div class='mx-auto max-w-screen-xl px-4 md:px-8'>
<div class='mb-10 md:mb-16'>
<h1 class='mb-4 text-center text-6xl font-thin text-primary md:mb-6 lg:text-7xl'>
ARTISTS
</h1>
<p class='mx-auto uppercase text-center max-w-screen-md text-secondary text-gray-500 md:text-lg'></p>
</div>
<div class='grid gap-8 mx-6 sm:grid-cols-2 sm:gap-12 lg:grid-cols-3 '>
{artists
.filter((artist) => {
if (searchTerm === '') {
return artist;
} else if (
artist.name.toLowerCase().includes(searchTerm.toLowerCase())
) {
return artist;
}
})
.map((artist) => (
<div>
<div
key={artist.id}
class='card w-96 max-w-xs bg-neutral text-neutral-content shadow-xl'>
<div class='card-body p-4 m-2 mx-0 items-center text-center'>
<div class='avatar'>
<div class='w-30 rounded'>
<img
src={artist.image}
alt='a small avatar of the musical artist'
/>
</div>
</div>
<h1 class='card-title'>{artist.name}</h1>
<p>{artist.genre.name}</p>
<div class='card-actions justify-end'>
<button
class='btn btn-primary'
onClick={() => navigate(`/artists/${artist.id}`)}>
view ticket activity
</button>
</div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</div>
);
}
export default ArtistsDisplay;
EachArtistCard.js
note: even with the two useEffects below commented out, thisArtist still =undefined
import React from 'react';
import { useParams } from 'react-router-dom';
import { useEffect, useState } from 'react';
import IndividualPost from './IndividualPost';
function EachArtistCard({ posts, setPosts, artists }) {
let { id } = useParams();
const thisArtist = artists.find(
(artist) => parseInt(id) === parseInt(artist.id)
);
//* to set selling & looking
useEffect(() => {
thisArtist.posts.map((each) => {
if (each.for_sale === true) {
setSelling(selling + 1);
} else {
setLooking(looking + 1);
}
});
}, []);
//* to set upcomingShows
useEffect(() => {
thisArtist.concerts.map((each) => setUpcomingShows(upcomingShows + 1));
}, []);
return (
<div>
<div class='bg-base-900 py-6 sm:py-8 lg:py-'>
<div class='mx-auto max-w-screen-xl px-4 md:px-8'>
<div class='mb-10 md:mb-16'>
<h1 class='mb-4 text-center text-6xl font-thin uppercase text-primary md:mb-6 lg:text-7xl'>
{thisArtist.name}
</h1>
</div>
<div class='flex justify-center'>
<div class='card w-96 bg-base-500 bg-neutral text-neutral-content justify-center shadow-2xl'>
<div class='avatar'>
<div class='w-30 rounded'>
<img
src={thisArtist.image}
alt='a small avatar of the music thisArtist'
/>
</div>
</div>
<div class='card-body items-center text-center'>
<h2 class='card-title'>{thisArtist.name}</h2>
<p>
There's {upcomingShows} upcoming concerts listed for{' '}
{thisArtist.name}!
</p>
<div>
<div class='badge badge-primary uppercase'>
{selling} selling
</div>
<div class='badge badge-primary uppercase'>
{looking} looking
</div>
</div>
<div class='card-actions justify-end'>
<button class='btn btn-secondary w-full'>
I have tickets to sell
</button>
<button class='btn btn-secondary w-full'>
I'm Looking For Tickets
</button>
<button class='btn btn-outline btn-black w-full'>
Go Back
</button>
</div>
</div>
</div>
</div>
<h2 class='my-10 text-center text-5xl font-thin uppercase text-primary md:mb-6 lg:text-6xl'>
ALL POSTS
</h2>
</div>
</div>
</div>
);
}
export default EachArtistCard;
App.js
removed a lot of other code not pertaining to the situation here
import '../../src/App.css';
import ArtistsDisplay from './ArtistsDisplay';
import ConcertsDisplay from './ConcertsDisplay';
import VenuesDisplay from './VenuesDisplay';
import GenreDisplay from './GenreDisplay';
import Login from './Login';
import SignUp from './SignUp';
import NotFound from './NotFound';
import Header from './Header';
import { Route, Routes } from 'react-router-dom';
import { useState, useEffect } from 'react';
import UsersPage from './UsersPage';
import EachArtistCard from './EachArtistCard';
function App() {
const [user, setUser] = useState('');
const [sessionInfo, setSessionInfo] = useState([]);
const [searchTerm, setSearchTerm] = useState('');
const [artists, setArtists] = useState([]);
useEffect(() => {
fetch('/artists')
.then((r) => r.json())
.then((info) => setArtists(info));
}, []);
return (
<div>
<Header
user={user}
setUser={setUser}
onLogin={onLogin}
onLogout={onLogout}
loggedIn={loggedIn}
/>
<Routes>
<Route
path='/'
element={
<UsersPage
user={user}
cookies={cookies}
sessionInfo={sessionInfo}
loggedIn={loggedIn}
/>
}
/>
<Route
path='/artists'
element={
<ArtistsDisplay
artists={artists}
genres={genres}
user={user}
posts={posts}
setPosts={setPosts}
searchTerm={searchTerm}
setSearchTerm={setSearchTerm}
showModal={showModal}
setShowModal={setShowModal}
/>
}
/>
<Route
path='/artists/:id'
element={
<EachArtistCard
artists={artists}
concerts={concerts}
posts={posts}
setPosts={setPosts}
user={user}
/>
}
/>
<Route path='*' element={<NotFound />} />
</Routes>
</div>
);
}
export default App;
Will take any steps in the right direction as I'm lost. If more info is needed, please let me know.

Related

React Route not adding forward slash with path="/post/:slug"

For some reason when I click on one of the posts in the collection of posts section to view the info on one single post, my code is not adding a forward slash / in the URL like so : http://localhost:3000/postyou-just-could-not-have where the URL I need is http://localhost:3000/post/you-just-could-not-have.
Is there a way to add a / to the URL or figure out why it is not being generated?
App.js with Route <Route path="/post/:slug" element={<SinglePost />} /> in question :
import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import SinglePost from './components/SinglePost';
import Post from './components/Post';
import Project from './components/Project';
import NavBar from './components/NavBar';
function App() {
return (
<Router>
<NavBar />
<Routes>
<Route path="/" element={<Home />} exact />
<Route path="/about" element={<About />} />
<Route path="/post/:slug" element={<SinglePost />} />
<Route path="/post" element={<Post />} />
<Route path="/project" element={<Project />} />
</Routes>
</Router>
);
}
export default App;
SinglePost.js component attempting to build URL from slug value :
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import sanityClient from '../client';
import BlockContent from '#sanity/block-content-to-react';
import imageUrlBuilder from '#sanity/image-url';
const builder = imageUrlBuilder(sanityClient);
function urlFor(source) {
return builder.image(source);
}
export default function SinglePage() {
const [singlePost, setSinglePost] = useState(null);
const { slug } = useParams();
useEffect(() => {
sanityClient
.fetch(
`*[slug.current == "${slug}"]{
title,
_id,
slug,
mainImage{
asset->{
_id,
url
}
},
body,
"name": author->name,
"authorImage": author->image
}`
)
.then((data) => setSinglePost(data[0]))
.catch(console.error);
}, [slug]);
if (!singlePost) {
return <div>Loading...</div>;
}
return (
<main className="bg-gray-200 min-h-screen p-12">
<article className="container shadow-lg mx-auto bg-green-100 rounded-lg">
<header className="relative">
<div className="absolute h-full w-full flex items-center justify-center p-8">
<div className="bg-white bg-opacity-75 rounded p-12">
<h1 className="cursive text-3xl lg:text-6xl mb-4">
{singlePost.title}
</h1>
<div className="flex justify-center text-gray-800">
<img
src={urlFor(singlePost.authorImage).url()}
alt="bob"
className="w-10 h-10 rouded-full"
/>
<p className="cursive flex items-center pl-2 text-2xl">
{singlePost.name}
</p>
</div>
</div>
</div>
<img
src={singlePost.mainImage.asset.url}
alt="gary"
className="w-full object-cover rounded-t"
style={{ height: '400px' }}
/>
</header>
<div className="px-16 lg:px-48 py-12 lg:py-20 prose lg:prose-xl max-w-full">
<BlockContent
blocks={singlePost.body}
projectId="notReally"
dataset="production"
/>
</div>
</article>
</main>
);
}
Adding Post.js :
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import sanityClient from '../client';
export default function Post() {
const [postData, setPost] = useState(null);
useEffect(() => {
sanityClient
.fetch(
`*[_type == "post"]{
title,
slug,
mainImage{
asset->{
_id,
url
},
alt
}
}`
)
.then((data) => setPost(data))
.catch(console.error);
}, []);
//anything wrapped in Link makes it clickable
return (
<main className="bg-green-100 min-h-screen p-12">
<section className="container mx-auto">
<h1 className="text-5xl flex justify-center cursive">Blog Post Page</h1>
<h2 className="text-lg text=gray-600 flex justify-center mb-12">
Welcome Doggies
</h2>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{postData &&
postData.map((post, index) => (
<article>
<Link to={'/post' + post.slug.current} key={post.slug.current}>
<span
className="block h-64 relative rounded shadow leading-snug bg-white border-l-8 border-green-400"
key={index}
>
<img
src={post.mainImage.asset.url}
alt="photo"
className="w-full h-full rounded-r object-cover absolute"
/>
<span className="block relative h-full flex justify-end items-end pr-4 pb-4">
<h3 className="text-gray-800 text-lg font-blog px-3 py-4 bg-red-700 text-red-100 bg-opacity-75 rounded">
{post.title}
</h3>
</span>
</span>
</Link>
</article>
))}
</div>
</section>
</main>
);
}
Links are relative to the route hierarchy by default, unless given a value begin with /.
More about Link
In <Post />, try one of the following:
<Link to={post.slug.current} key={post.slug.current}>
...
/Link>
Or:
<Link to={'/post/' + post.slug.current} key={post.slug.current}>
...
/Link>
These will hopefully generate the right path as /post/:slug.

How to get the name of the user that was clicked and send it to another component?

I'm having a problem that I can't solve. I have a component that is currently rendering the users that are in my database, which calls CarouselUsers.jsx, so far so good, it is showing correctly.
But my goal is that after I click on one of these users that were listed, his name appears in a sidebar, which is in another component, but I am not able to do that, can you help me?
CarouselUsers.jsx
import React, { useState, useEffect } from 'react';
import * as Styled from './style.jsx';
import {
collection,
getDocs,
} from "firebase/firestore";
import { Swiper, SwiperSlide } from "swiper/react";
import { db } from '../../Data/Firebase.jsx';
import "swiper/css";
import euTeste from '../../assets/teste.jfif'
import SideBarProfile from '../../components/SideBarProfile/SideBarProfile.jsx';
export default function CarouselUsers() {
const [profile, setProfile] = useState(false)
const openProfile = () => {
setProfile(profile => !profile)
}
// USERS IN THE DB
const [users, setUsers] = useState([])
const usersCollectionRef = collection(db, "usuarios")
useEffect(() => {
const getUsers = async () => {
const data = await getDocs(usersCollectionRef);
setUsers(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
};
getUsers();
}, []);
// USERS IN THE DB
return (
<>
<Styled.CarouselUsers>
{/* MEMBROS CARROSEL */}
<div className="boxMembros">
<div className="titulo">
<h6>Membros</h6>
</div>
<Swiper
spaceBetween={10}
slidesPerView={3}
>
{users.map((user) => {
return (
<>
<SwiperSlide>
<div className="box"style={{ background: `linear-gradient(to bottom,rgba(0, 0, 0, 0.4) 0,rgba(0,0,0,.6) 100%),url(${euTeste})` }} onClick={openProfile} key={user.nome}>
<div className="infoBottom">
<div className="info">
{/* GET THE USERNAME */}
<h6>{user.nome}</h6>
{/* GET THE USERNAME */}
</div>
</div>
</div>
</SwiperSlide>
</>
);
})}
</Swiper>
</div>
{/* MEMBROS CARROSEL */}
</Styled.CarouselUsers>
<SideBarProfile profile={profile} openProfile={openProfile} />
</>
)
}
SideBarProfile.jsx
import React from 'react'
import { XCircle,WhatsappLogo } from "phosphor-react";
import * as Styled from './style.jsx';
export default function SideBarProfile({openProfile,profile}) {
return (
<Styled.SideBarProfile>
<div className={profile ? 'col-md-3 boxLeftWrapper open' : 'col-md-3 boxLeftWrapper close'} profile={profile}>
<div className="boxAll">
<div className="header d-flex justify-between align-items-center">
<div className="titulo">
<h1>Perfil</h1>
</div>
<div className="close">
<button onClick={openProfile}>
<XCircle/>
</button>
</div>
</div>
<div className="boxBodyUser text-left">
<div className="boxThis">
<div className="foto">
<img alt="Usuário" className='img-fluid ativo' />
</div>
<div className="nome text-center">
<h5>{/* SHOW USERNAME */}</h5>
</div>
<div className="status ativo">
<span>Ativo</span>
</div>
<div className="ministerios">
<ul className="pl-0 list-none mb-0">
<li>Teatro</li>
<li>Mídias Sociais</li>
</ul>
</div>
<div className="boxContato mt-5">
<div className="whatsapp d-flex items-center justify-center gap-2">
<WhatsappLogo/>
<span>Mensagem</span>
</div>
</div>
</div>
</div>
</div>
</div>
</Styled.SideBarProfile>
)
}
You can add an onClick event in your CarouselUsers component that grab the Inner Text in <h6>{user.nome}</h6> and pass it as props to SideBarProfile component .
like this :
CarouselUsers.jsx :
export default function CarouselUsers() {
const [profile, setProfile] = useState(false)
const [selectedUser, setSelectedUser] = useState("")
const handleClick = (event) => {
setSelectedUser(event.target.innerText);
}
// rest of your code
return (
......
{/* GET THE USERNAME */}
<h6 onClick={handleClick} >{user.nome}</h6>
{/* GET THE USERNAME */}
.... rest of your code
<SideBarProfile profile={profile} openProfile={openProfile}
setSelectedUser = {setSelectedUser} />
)
}
SideBarProfile.jsx :
export default function SideBarProfile({openProfile,profile, setSelectedUser}) {
return (
......
<div className="nome text-center">
<h5>{setSelectedUser}</h5>
</div>
....
)

Deleting component with api only disappears after refresh Reactjs

I have a spring boot api with crud functionalities, on my react frontend I have this, which is a dashboard component and inside i am rendering a list of ProjectItem components and passing them to the dashboard component as props.
When I delete a project I'd like it to immediately remove the project from the component without having to refresh for it to happen.
Since I am passing the props down to my Dashboard component I am a bit confused on how to achieve this.
ProjectItem.js
BackendService is a service class with axios calls for the crud operations
import React, { useEffect, useState } from 'react'
import BackendService from '../services/BackendService';
import { Link } from 'react-router-dom';
import { useParams } from 'react-router';
const ProjectItem = ({projectName, projectIdentifier, description}) => {
const onDeleteClick = (id) => {
if (window.confirm("Are you sure you want to delete this project?")) {
BackendService.deleteProject(id)
.then()
.catch((err) => {
console.log(err.response);
});
alert("Project with ID " + id + " was deleted successfully");
}
};
return (
<div className="container">
<div className="card card-body bg-light mb-3">
<div className="row">
<div className="col-2">
<span className="mx-auto">{projectIdentifier}</span>
</div>
<div className="col-lg-6 col-md-4 col-8">
<h3>{projectName}</h3>
<p>{description}</p>
</div>
<div className="col-md-4 d-none d-lg-block">
<ul className="list-group">
<Link to="">
<li className="list-group-item update">
<i className="fa fa-edit pr-1"> Update Project Info</i>
</li>
</Link>
<button
className="list-group-item delete"
onClick={() => onDeleteClick(projectIdentifier)}
>
<i className="fa fa-minus-circle pr-1"> Delete Project</i>
</button>
</ul>
</div>
</div>
</div>
</div>
);
};
export default ProjectItem;
Dashboard.js
Where the ProjectItem components are rendered
import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import BackendService from '../services/BackendService'
import AppNavbar from './AppNavbar'
import ProjectItem from './ProjectItem'
const Dashboard = () => {
const [project, setProject] = useState({
projectName: "",
projectIdentifier: "",
description: "",
});
useEffect(() => {
BackendService.getProjects().then((res) => {
setProject(res.data);
});
}, []);
return (
<div className="projects">
<AppNavbar />
<div className="container">
<div className="row">
<div className="col-md-12">
<h1 className="display-4 text-center">Projects</h1>
<Link to="/addProject">
<button className="btn btn-warning">Create Project</button>
</Link>
{project &&
Object.values(project).map((prj) => {
return (
<div>
<ProjectItem key={prj.id}
projectName={prj.projectName}
projectIdentifier={prj.projectIdentifier}
description={prj.description}
/>
</div>
);
})}
<hr />
</div>
</div>
</div>
</div>
);
};
export default Dashboard
If you want to remove item without refresh the page then you have to call setProject and set it to new project list after BackendService.deleteProject request done in onDeleteClick.
https://reactjs.org/docs/state-and-lifecycle.html

Having trouble filtering the data from json

Hello again Stackoverflow members.I have GLS Component I have more similiar components to GLS concept is the same but styling is not, anyway the thing I want to achieve is this, when I press on the Link in GLS/A Component I want to display/Render the image class and price of that Component on the payment page for some reason it is giving me this error 'TypeError: Cannot read property 'image' of undefined'. I would be very grateful if someone could help me.
Gls Component
import React from "react";
import data from "../data.json";
import { Link } from "react-router-dom";
function GLS({product}) {
return (
<div>
<div key={product.id} className="m-4 bg-blue-100 rounded-xl p-8 absolute ">
<div>
<Link
to={`/payment/${product.id}`}
className="py-1 px-2 text-black-600 h-10 ml-24 mt-32 bg-white w-
36 rounded-full focus:outline-none focus:ring-2 focus:ring-gray-600"
>
Buy Now
</Link>
<img
alt=""
className="w-screen object-contain"
src={product.image}
></img>
<h1 className=" ml-24 md:text-5xl sm:text-5xl top-8">
{product.class}
</h1>
<h1 className="text-base font-mono ml-24 top-24">
{product.price}
</h1>
</div>
</div>
</div>
);
}
export default GLS;
App Component
import React,{useState, useEffect} from 'react'
import './assets/main.css'
import A from './Models/GLS Model/A'
import GLS from './Models/GLS Model/GLS'
import data from "./Models/data.json";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
return (
<div className='' >
<div >
<Router>
<Switch>
<Route path="gls">
{data.map((product) => (
<GLS key={product.id} product={product} />
))}
</Route>
<Route path="a">
{data.map((product) => (
<A key={product.id} product={product} />
))}
</Route>
<Route path="/payment/:productId">
<Payment />
</Route>
<Route exact path="/">
<Home />
</Route>
</Switch>
</Router>
</div>
</div>
);
}
export default App;
import React from 'react'
import {
Link,
} from "react-router-dom";
import data from "./Models/data.json";
function Home() {
return (
<div className='ml-20'>
<nav className='bg-red-50 max-w-full'>
<ul >
<li>
<Link to='/gls'>GLS-class</Link>
</li>
<li>
<Link to="/a"> A-Class</Link>
</li>
</ul>
</nav>
</div>
)
}
export default Home
Payment Component
import React from "react";
import { useParams } from "react-router-dom";
import data from "./Models/data.json";
const Payment = () => {
const { productId } = useParams();
const filteredData = data.filter((product) => product.id === productId)[0];
return (
<div className="ml-20">
<img alt="" className="w:2/4 object-contain " src={filteredData.image} />
<h2
className=" ml-24 mlg:ml-6 mlg:mt-2 mlg:static text-5xl mlg:text-2xl text-blue-400 absolute top-
48"
>
{filteredData.class}
</h2>
<h3
className="text-lg mlg:mb-2 mlg:ml-6 mlg:mt-2 mlg:static font-bold text-green-800
font-mono ml-24 top-64 absolute"
>
{filteredData.price}
</h3>
</div>
);
};
export default Payment;
Json file
[
{
"id": 0,
"class": "A-Class",
"image": "./ModImages/Aclass.jpg",
"price": "It goes around $37,300",
},
{
"id": 1,
"class": "GLS-Class",
"image": "./ModImages/GLSclass.jpg",
"price": "It goes around $47,700"
}
]
TypeError: Cannot read property 'image' of undefinedThis is a great error to have because it more or less tells you exactly what's wrong. In basic terms, undefined means that a variable has been declared but has not yet been assigned a value.
function myFunc(product) {
return product.img;
}
var product; //initialized to undefined, must explicitly set type;
console.log(myFunc(product));
Result -> Uncaught TypeError: product is undefined
function myFunc(product) {
return product.img;
};
var product; //undefined
product = {}; //explicitly setting to object
product.img = 'image'; // set a name and value
console.log(myFunc(product));

React Hooks to filter through list

I am using react/redux & would like to filter through posts that are from my backend in Node. I am mapping through the posts and they are being shown. Trying to implement a filter input I am looking for some advice on how to use react hooks to get this working.
My component...
import React, { Fragment, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import Spinner from '../layout/Spinner';
import { getCommunityPosts } from '../../actions/communitypost';
import CommunityPostItem from './CommunityPostItem';
import Cooking from '../../img/vegetables.jpg';
import Lifestyle from '../../img/lifestyle.jpg';
import General from '../../img/general.jpg';
// Lazy load
import { LazyLoadImage } from 'react-lazy-load-image-component';
import 'react-lazy-load-image-component/src/effects/blur.css';
const CommunityPosts = ({
getCommunityPosts,
communitypost: { posts, loading }
}) => {
const [searchTerm, setSearchTerm] = useState("");
const [searchPosts, setSearchPosts] = useState([]);
const handleChange = e => {
setSearchTerm(e.target.value);
}
useEffect(() => {
const results = posts.filter(post => {
console.log(post);
post.toLowerCase().includes(searchTerm)
}
);
setSearchPosts(results)
getCommunityPosts();
}, [getCommunityPosts, searchTerm]);
return (
loading ? (
<Spinner />
) : (
<Fragment>
<Fragment>
<div className="search-recipes">
<input
className="bg-white focus:outline-none focus:shadow-outline border border-gray-300 rounded-lg py-2 px-4 block w-full appearance-none leading-normal"
type="text"
value={searchTerm}
onChange={handleChange}
placeholder="Search community posts..."
></input>
</div>
<div className="pt-1 grid lg:grid-cols-3 md:grid-cols-2 sm:grid-cols-1 gap-1">
<div className="cursor-pointer category-overlay">
<Fragment>
<Link to="/communityposts/category/cooking">
<LazyLoadImage effect="blur" src={Cooking}></LazyLoadImage>
<div className="content">
<div className="recipe-category-text pacifico">Cooking</div>
</div>
</Link>
</Fragment>
</div>
<div className="cursor-pointer category-overlay">
<Fragment>
<Link to="/communityposts/category/lifestyle">
<LazyLoadImage effect="blur" src={Lifestyle}></LazyLoadImage>
<div className="content">
<div className="recipe-category-text pacifico">Lifestyle</div>
</div>
</Link>
</Fragment>
</div>
<div className="cursor-pointer category-overlay">
<Fragment>
<Link to="/communityposts/category/general">
<LazyLoadImage effect="blur" src={General}></LazyLoadImage>
<div className="content">
<div className="recipe-category-text pacifico">General</div>
</div>
</Link>
</Fragment>
</div>
</div>
</Fragment>
<Fragment>
<div className="community-posts bg-gray-200">
{posts.map(post => (
<CommunityPostItem key={post._id} post={post} />
))}
</div>
</Fragment>
</Fragment>
)
);
};
CommunityPosts.propTypes = {
getCommunityPosts: PropTypes.func.isRequired,
communitypost: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
communitypost: state.communitypost
});
export default connect(mapStateToProps, { getCommunityPosts })(CommunityPosts);
Error i'm getting is that "TypeError: post.toLowerCase is not a function"

Categories