I was following one of the tutorials when this issue came up. I am using React js with Firebase Cloud Firestore. In the code, the component called Post is not rendering on the screen! There is no error shown either. No warnings !
Here's the code of Feed.js
import React, { useState, useEffect } from "react";
import TweetBox from "./TweetBox";
import Post from "./Post";
import "./Feed.css";
import db from "./firebase";
import FlipMove from "react-flip-move";
function Feed() {
const [posts, setPosts] = useState([]);
useEffect(() => {
db.collection("posts").onSnapshot((snapshot) => {
setPosts(snapshot.docs.map((doc) => doc.data()));
});
}, []);
return (
<div className="feed">
<div className="feed__header">
<h2>Home</h2>
</div>
<FlipMove>
{posts &&
posts.map((post) => {
<Post
key={post.text}
displayName={post.displayName}
userName={post.userName}
verified={post.verified}
text={post.text}
avatar={post.avatar}
image={post.image}
/>;
})}
</FlipMove>
</div>
);
}
export default Feed;
Code of Post.js
import React, { forwardRef } from "react";
import "./Post.css";
import { Avatar } from "#material-ui/core";
import VerifiedUserIcon from "#material-ui/icons/VerifiedUser";
import ChatBubbleOutlineIcon from "#material-ui/icons/ChatBubbleOutline";
import RepeatIcon from "#material-ui/icons/Repeat";
import FavoriteBorderIcon from "#material-ui/icons/FavoriteBorder";
import PublishIcon from "#material-ui/icons/Publish";
const Post = forwardRef(
({ displayName, userName, verified, text, image, avatar }, ref) => {
return (
<div className="post" ref={ref}>
<div className="post__avatar">
<Avatar src={avatar} />
</div>
<div className="post__body">
<div className="post__header">
<div className="post__headerText">
<h3>
{displayName}{" "}
<span className="post__headerSpecial">
{verified && <VerifiedUserIcon className="post__badge" />} #
{userName}
</span>
</h3>
</div>
<div className="post__headerDescription">
<p>{text}</p>
</div>
</div>
<img src={image} alt="" />
<div className="post__footer">
<ChatBubbleOutlineIcon fontSize="small" />
<RepeatIcon fontSize="small" />
<FavoriteBorderIcon fontSize="small" />
<PublishIcon fontSize="small" />
</div>
</div>
</div>
);
}
);
export default Post;
Any help is greatly appreciated !
return is missing.
posts.map((post) => {
return <Post
key={post.text}
displayName={post.displayName}
userName={post.userName}
verified={post.verified}
text={post.text}
avatar={post.avatar}
image={post.image}
/>;
})}
if you don't wanna write return, you can wrap your component with ()
posts.map((post) => (<Post //your other props here/>))}
Related
I admit that I am not very expert, and I need help with this
this is my "posts" component which is in charge of making an api call to get the data of all posts:
import React from 'react'
import Post from '../post/Post';
import "./posts.scss"
import { useQuery } from 'react-query'
import {makeRequest} from '../../axios'
const Posts = () => {
const { isLoading, error, data } = useQuery('posts', () =>
makeRequest.get("/posts").then((res) =>{
return res.data;
})
);
return (
<div className='posts'>
{data?.map(post=>(
<Post post={post} key={post.id}/>
))}
</div>
)
}
export default Posts
this component makes the "map" of the data it has received and passes the data to the "post" component which takes care of displaying the data for each single post received.
import React, { useState } from "react";
import "./post.scss";
import FavoriteBorderOutlinedIcon from "#mui/icons-material/FavoriteBorderOutlined";
import FavoriteOutlinedIcon from "#mui/icons-material/FavoriteOutlined";
import TextsmsOutlinedIcon from "#mui/icons-material/TextsmsOutlined";
import ShareOutlinedIcon from "#mui/icons-material/ShareOutlined";
import MoreHorizIcon from "#mui/icons-material/MoreHoriz";
import { Link } from "react-router-dom";
import Comments from "../comments/Comments";
import moment from "moment";
import Updatepost from "../updatePost/Updatepost";
const Post = ({ post }) => {
const [commentOpen, setCommentOpen] = useState(false);
const [isLiked, setIsLiked] = useState(false);
const [menuOpen, setMenuOpen] = useState(false);
const [openUpdate, setOpenUpdate] = useState(false);
return (
<div className="post">
<div className="container">
<div className="user">
<div className="userInfo">
<img src={post.profilePic} />
<div className="details">
<Link
to={`/profile/${post.userId}`}
style={{ textDecoration: "none", color: "inherit" }}
>
<span className="name">{post.name}</span>{" "}
</Link>
<span className="date">{moment(post.createdAt).fromNow()}</span>
</div>
</div>
<MoreHorizIcon onClick={() => setMenuOpen(!menuOpen)} />
{menuOpen && (
<button
onClick={() => {
setOpenUpdate(true);
setMenuOpen(false);
}}
>
Modifica
</button>
)}
</div>
<div className="content">
<p>{post.desc}</p>
<img src={"./upload/" + post.img} alt=""></img>
</div>
<div className="info">
<div className="item " onClick={() => setIsLiked(!isLiked)}>
{isLiked ? (
<FavoriteOutlinedIcon />
) : (
<FavoriteBorderOutlinedIcon />
)}
12 Mi piace
</div>
<div className="item" onClick={() => setCommentOpen(!commentOpen)}>
<TextsmsOutlinedIcon />4 Commenti
</div>
<div className="item">
<ShareOutlinedIcon />8 Condivisioni
</div>
</div>
{commentOpen && <Comments />}
</div>
{openUpdate && (
<Updatepost setOpenUpdate={setOpenUpdate} post={this.post} />
)}
</div>
);
};
export default Post;
as you can see, i'm trying to pass the post data to the "UpdatePost" component to be able to do an update query later but when i try to do it saying
<Updatepost setOpenUpdate={setOpenUpdate} post={post} or <Updatepost setOpenUpdate={setOpenUpdate } post={this.post}/> tells me, doing the console log of the data on the Updatepost component that is undefined, someone can help e please?
As I said, I tried changing the "post" entry to this.post when passing props, but it didn't help. I need the data of the post I'm trying to modify in order to then perform the queries I need
thanks to all for the very fast response, while I was preparing an example on code sandbox, I realized that the declaration of the parameters in Updatepost was done like this {setOpenUpdate}, {post} instead of {setOpenUpdate, post}
I am creating a chat app. The app returns a blank page after the login page, instead of showing the chat section. The problem is with the firebase code which I used for getting the messages from the firebase database. If I don't render the Chat section, then the Sidebar section turns out to render well. The Chat component code is:
import React, { useEffect, useState } from "react";
import "./Chat.css";
import { Avatar, IconButton } from "#material-ui/core";
import { SearchOutlined } from "#material-ui/icons";
import { AttachFile } from "#material-ui/icons";
import MoreVertIcon from "#material-ui/icons/MoreVert";
import MicIcon from "#material-ui/icons/Mic";
import InsetEmoticonIcon from "#material-ui/icons/InsertEmoticon";
import { useParams } from "react-router-dom";
import db from "./firebase";
function Chat() {
const [input, setInput] = useState("");
const [photo, setphoto] = useState("");
const [messages, setMessages] = useState();
const { roomId } = useParams();
const [roomName, setRoomName] = useState();
useEffect(() => {
if (roomId) {
console.log("Change");
db.collection("rooms")
.doc(roomId)
.onSnapshot((snapshot) => setRoomName(snapshot.data().name));
db.collection("rooms")
.doc(roomId)
.collection("messages")
.orderBy("timestamp", "asc")
.onSnapshot((snapshot) =>
setMessages(snapshot.docs.map((doc) => doc.data()))
);
}
}, [roomId]);
useEffect(() => {
setphoto(Math.floor(Math.random() * 5000));
}, []);
const sendMessage = (e) => {
e.preventDefault();
console.log("You typed a message");
setInput("");
};
return (
<div className="chat">
<div className="chat-header">
<Avatar
src={`https://avatars.dicebear.com/api/pixel-art/${photo}.svg`}
/>
<div className="chat-headerInfo">
<h2>{roomName}</h2>
<p>Last Seen</p>
</div>
<div className="chat-headerRight">
<IconButton>
<SearchOutlined />
</IconButton>
<IconButton>
<AttachFile />
</IconButton>
<IconButton>
<MoreVertIcon />
</IconButton>
</div>
</div>
<div className="chat-body">
{messages.map((message) => (
<p className="chat-message chatReceiver">
<span className="sender">{message.name}</span>
{message.message}
<span className="timestamp">
{new Date(message.timestamp?.toDate()).toUTCString}
</span>
</p>
))}
</div>
<div className="chat-footer">
<InsetEmoticonIcon />
<form>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
type="text"
placeholder="Type a message"
/>
<button onClick={sendMessage} type="submit">
Send a message
</button>
</form>
<MicIcon />
</div>
</div>
);
}
export default Chat;
Github link of the project : https://github.com/aditramdas/Chat-App/tree/main/chat-app-new/src
I tried it from last 2 days but can not getting the solution. I tried many times please help me out.If any one knows please help me thanks in advance
Trying to fetch the details of room while clicking on Book Now button but Getting error:src\screen\Bookingscreen.js Line 21:8:
React Hook useEffect has a missing dependency: 'match.params.roomid'. Either include it or remove the dependency array
Here is my code :
````Bookingscreen.js
import React, { useState, useEffect } from 'react'
import axios from "axios"
function Bookingscreen({ match }) {
const [loading, setloading] = useState(true);
const [error, setError] = useState();
const [room, setroom] = useState();
useEffect(() => {
async function postData() {
try {
setloading(true);
const data = (await axios.post('/api/rooms/getroombyid', { roomid: match.params.roomid })).data; // Here I got the Error
setroom(data);
setloading(false);
} catch (error) {
console.log(error)
setloading(false);
setError(true);
}
}; postData();
}, []);
return (
<div className='m-5'>
{loading ? (<h1>loading...</h1>) : error ? (<h1>Error...</h1>) : (<div>
<div className='row justif-content-center mt-5 bs'>
<div className='col-md-6'>
<h1>{room.name}</h1>
<img src={room.imageurls[0]} className='bigimg' />
</div>
<div style={{ float: "right" }}>
<div className='col-md-6'>
<b>
<h1>Bookin Details</h1>
<hr />
<p>Name:</p>
<p>From Date :</p>
<p>To Date :</p>
<p>Max Count : {room.maxcount}</p>
</b>
</div>
<div style={{ float: "right" }}>
<b>
<h1>Amount</h1>
<hr />
<p>Total days: </p>
<p>Rent per day: {room.rentperday}</p>
<p>Total Amount</p>
</b>
</div>
<div style={{ float: "right" }}>
<button className='btn btn-primary'>Pay Now</button>
</div>
</div>
</div>
</div>)}
</div>
)
}
export default Bookingscreen;
````App.js file:
From App.js I used the Route for fetch roomid:
import logo from './logo.svg';
import './App.css';
import Navbar from './components/Navbar';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'
import HomeScreen from './screen/HomeScreen';
import Bookingscreen from './screen/Bookingscreen';
function App() {
return (
<div className="App">
<Router>
<Navbar />
<Routes>
<Route exact path="/" element={<HomeScreen />} />
<Route path="/book/:roomid" element={<Bookingscreen />} />
</Routes>
</Router>
</div>
);
}
export default App;
````Room.js file:
import React, { useState } from 'react'
import { Modal, Button, Carousel } from 'react-bootstrap'
import { Link } from 'react-router-dom'
function Room({ room }) {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<div className='row bs'>
<div className='col-md-4'>
<img src={room.imageurls[0]} alt='' className='smallimg' />
</div>
<div className='col-md-7'>
<h1>{room.name}</h1>
<b>
{" "}
<p>Max Count: {room.maxcount}</p>
<p>Phone Number: {room.phonenumber}</p>
<p>Type: {room.type}</p>
</b>
<div style={{ float: 'right' }}>
<Link to={`/book/${room._id}`}>
<button className='btn btn-primary m-2'>Book Now</button>
</Link>
<button className='btn btn-primary' onClick={handleShow}>View Details</button>
</div>
</div>
<Modal show={show} onHide={handleClose} size='lg'>
<Modal.Header>
<Modal.Title>{room.name}</Modal.Title>
</Modal.Header>
<Modal.Body>
<Carousel>
{room.imageurls.map(url => {
return <Carousel.Item>
<img
className="d-block w-100 bigimg"
src={url}
alt="room-images"
/>
</Carousel.Item>
})}
</Carousel>
{room.description}
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
</Modal.Footer>
</Modal>
</div>
)
}
export default Room
````roomsRoute.js file:
const express=require('express');
const router=express.Router();
const Room=require("../models/roomModel");
//book a room
router.post("/getroombyid", async(req,res)=>{
try {
const room=await Room.findOne({_id:req.params.roomid})
res.send("Successful");
} catch (error) {
return res.status(400).json({message:"error"});
}
});
module.exports=router;
Inside Bookingscreen you are using the useEffect hook which has an optional second property which should contain a list of dependencies which the function "watches" for changes. If you want it to run once like didComponentMount then remove the second parameter (i.e. remove []), otherwise add dependencies.
Edit: Either of these will get rid of the error:
function Bookingscreen({ match }) {
// ...
useEffect(() => {
// ...
})
// OR
useEffect(() => {
// ...
}, [match.params.roomid])
This is an ESLint (eslint-plugin-react-hooks) warning . that tell you your useEffect is depends on 'match.params.roomid'
to prevent this warning just add it as a dependency array in your useEffect like this :
useEffect(() => {
async function postData() {
try {
setloading(true);
const data = (await axios.post('/api/rooms/getroombyid', { roomid: match.params.roomid })).data; // Here I got the Error
setroom(data);
setloading(false);
} catch (error) {
console.log(error)
setloading(false);
setError(true);
}
}; postData();
}, [match.params.roomid]);
or disable Eslint's warning :
useEffect(() => {
your code here ...
}, []) // eslint-disable-line react-hooks/exhaustive-deps
Everything is normal even in the console, if I delete the image, the other information appears, but when I add an image, it does not recognize it ,
How can I solve this problem
import React, { useEffect, useState } from 'react';
import './SinglePage.css';
import Style from '../../components/styles/Style';
import Logo from '../../components/Logo/Logo';
import Navbar from '../../components/Navbar/Navbar';
import RightBar from '../../components/RightBar/RightBar';
import { useParams } from 'react-router';
import API from '../../api/Api';
import Loading from '../../components/loading/Loading';
const SinglePage = () => {
const [loading , setLoading] = useState(true);
const [Data , setData] = useState([]);
const [message , setMessage] = useState();
const id = useParams();
const URL = 'http://localhost:8001/'
useEffect(() => {
API.get("api/GetPosts").then((res) => {
if (res.data.AllData.length === 0) {
setMessage(true);
} else {
const card= res.data.AllData.find(x => x._id === id.id)
setData(card);
setLoading(true);
}
});
}, [])
return (
<>
<div>
<Logo />
<Navbar />
<div style={Style}>
<RightBar />
<div className="SinglePage-Container">
{loading && (
<div style={{margin:'0 auto', marginTop:'2rem' , display:'flex' , justifyContent:'center' , alignItems:'center'}}>
<Loading/>
</div>
)}
{message ? (
<div style={{margin:'0 auto', marginTop:'2rem' , display:'flex' , justifyContent:'center' , alignItems:'center'}}>
<h1>لا يوجد مقالة في هذا الرابط </h1>
</div>
) : (
<>
<div className="SinglePage-Image">
<img src={`${URL}${Data.images[0].filename}`} alt=''/>
</div>
<div className="SinglePage-Title">
{Data.title}
</div>
<p>
{Data.article}
</p>
</>
)}
</div>
</div>
</div>
</>
)
}
export default SinglePage
From the comments I gather you get an object back from your API and your default value for Data is an array which would then be wrong.
And to make sure you render the image only once the image has been retrieved from the API you can use this:
DATA.images && <img src={`${URL}${Data.images[0].filename}`} alt=''/>
All together now:
import React, { useEffect, useState } from 'react';
import './SinglePage.css';
import Style from '../../components/styles/Style';
import Logo from '../../components/Logo/Logo';
import Navbar from '../../components/Navbar/Navbar';
import RightBar from '../../components/RightBar/RightBar';
import { useParams } from 'react-router';
import API from '../../api/Api';
import Loading from '../../components/loading/Loading';
const SinglePage = () => {
const [loading , setLoading] = useState(true);
const [Data , setData] = useState({});
// ^-- CHANGE
const [message , setMessage] = useState(false);
// ^-- CHANGE
const id = useParams();
const URL = 'http://localhost:8001/'
useEffect(() => {
API.get("api/GetPosts").then((res) => {
if (res.data.AllData.length === 0) {
setMessage(true);
} else {
const card= res.data.AllData.find(x => x._id === id.id)
setData(card);
setLoading(true);
}
});
}, [])
return (
<>
<div>
<Logo />
<Navbar />
<div style={Style}>
<RightBar />
<div className="SinglePage-Container">
{loading && (
<div style={{margin:'0 auto', marginTop:'2rem' , display:'flex' , justifyContent:'center' , alignItems:'center'}}>
<Loading/>
</div>
)}
{message ? (
<div style={{margin:'0 auto', marginTop:'2rem' , display:'flex' , justifyContent:'center' , alignItems:'center'}}>
<h1>لا يوجد مقالة في هذا الرابط </h1>
</div>
) : (
<>
<div className="SinglePage-Image">
{
DATA.images && <img src={`${URL}${Data.images[0].filename}`} alt=''/>
}
{/* ^--- CHANGE */}
</div>
<div className="SinglePage-Title">
{Data.title}
</div>
<p>
{Data.article}
</p>
</>
)}
</div>
</div>
</div>
</>
)
}
export default SinglePage
It reads:
"Error: App(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null."
I have seen other thread with about this particular issue with JS React but the solutions didn't work for me. I was making a shopping cart app with React and it was working fine when everything was on one JSX page but when I start making files for every every compartment for example, "Products, "Cart". . I am aware others have had this problem but I believe there are different ways you can get this error message.
Index.js:
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
App.js
const PAGE_PRODUCTS = 'products';
const PAGE_CART = 'cart';
function App() {
const [cart, setCart] = useState([]);
const [page, setPage] = useState(PAGE_PRODUCTS);
const addToCart = (product) =>{
console.log('we are in fart i mean cart');
setCart([...cart, {...product}]);
const removeFromCart = (productToRemove) =>{
setCart(
cart.filter(product => product !== productToRemove ));
};
const navigateTo = (nextPage) => {setPage(nextPage);
};
const renderCart = () => (
<>
<h1>Cart</h1>
<div className="products">
{cart.map ((product, idx) => (
<div className="product" key={idx}>
<h3>{product.name}</h3>
<h4>{product.cost}</h4>
<img src={product.image} alt={product.name}/>
<button onClick = {() => removeFromCart(product)}>Remove</button>
</div>
))}
</div>
</>
);
return (
<div className="App">
<header>
<button onClick={() => navigateTo(PAGE_CART)}>Go to Cart ({cart.length})</button>
<button onClick={() => navigateTo(PAGE_PRODUCTS)}>View Products </button>
</header>
{page === PAGE_PRODUCTS && (
<Products addToCart={addToCart} />
)}
{page === PAGE_CART && renderCart()}
</div>
);
};
}
export default App;
Products.jsx
import React, { useState } from 'react';
export default function Products({ addToCart }){
const [products] = useState([
{
name: 'TWA FUCK 12 T-SHIRT',
cost: '$19.99',
image: 'https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/ba6f3a5b-075f-4fae-9efd-dd797e00931a/ddya15n-0c2ea56a-4735-470c-bee9-41dd09f9dfb9.png/v1/fill/w_250,h_250,strp/blue_lives_splatter_by_0r4lf1x4t10n_ddya15n-250t.png?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOiIsImlzcyI6InVybjphcHA6Iiwib2JqIjpbW3siaGVpZ2h0IjoiPD0xMjgwIiwicGF0aCI6IlwvZlwvYmE2ZjNhNWItMDc1Zi00ZmFlLTllZmQtZGQ3OTdlMDA5MzFhXC9kZHlhMTVuLTBjMmVhNTZhLTQ3MzUtNDcwYy1iZWU5LTQxZGQwOWY5ZGZiOS5wbmciLCJ3aWR0aCI6Ijw9MTI4MCJ9XV0sImF1ZCI6WyJ1cm46c2VydmljZTppbWFnZS5vcGVyYXRpb25zIl19.bhFc4MR_BfROHMtp2C6Nl2GaQ1PeJS2piOioT3tyRgc'
},
{
name: 'TWA THE WORLD IS YOURS T-SHIRT',
cost: '$19.99',
image: 'https://ih1.redbubble.net/image.974235379.7506/poster,504x498,f8f8f8-pad,600x600,f8f8f8.jpg'
}
]);
return (
<>
<h1>Products</h1>
<div className="products">
{products.map ((product, idx) => (
<div className="product" key={idx}>
<h3>{product.name}</h3>
<h4>{product.cost}</h4>
<img src={product.image} alt={product.name}/>
<button onClick = {() => addToCart(product)}>Add To Cart</button>
</div>
))}
</div>
</>
);
}