render specific text based on Conditional statement - javascript

I have the following JSON
{"location":"2034","type":"Residential","price":400000,"address":"123 Fake Street","suburb":"Maroubra","historical_DAs":0,"description":"Residential","property_ID":1},
{"location":"2036","type":"Commercial","price":475000,"address":"123 Fake Street","suburb":"Coogee","historical_DAs":10,"description":"Government","property_ID":2},
{"location":"2035","type":"Food & Bev","price":56000,"address":"123 Fake Street","suburb":"Clovelly","historical_DAs":3,"description":"Residential","property_ID":3},
{"location":"2031","type":"Education","price":69070,"address":"123 Fake Street","suburb":"Randwick","historical_DAs":7,"description":"Government","property_ID":4},
{"location":"2036","type":"Education","price":69070,"address":"123 Fake Street","suburb":"Randwick","historical_DAs":7,"description":"Government","property_ID":5}
I want to render different images based upon the description field (currently trying to just get text to render correctly atm.)
What I have tried so far:
function TypeImages({ description }) {
function Residential(props) {
return <div>
<h1>Image 1</h1>
</div>;
}
function Government(props) {
return <div>
<h1>Image 2 </h1>
</div>;
}
function TypeImage(props) {
if (description === 'Residential') {
return <Residential />;
} else
return <Commercial />;
}
return (
<div>
<div>
<div className="hidden lg:inline-flex mb-1 px-9">
<TypeImage/>
<div>
</div>
</div>
</div>
</div>
);
}
export default TypeImages;
This isn't working as what is rendered is all 'Image 2' even though there should be some 'Image 1'
Any suggestions on the most efficient way to achieve this?
Thanks!

You can do by many ways,
You need to make sure or check if description has value, if not you probably get unexpected behaviors
Sandbox Example: https://codesandbox.io/s/stupefied-water-sc4o5h?file=/src/App.js
Using ternary conditional statements
return (
<div>
<div>
<div className="hidden lg:inline-flex mb-1 px-9">
{/* Doing this */}
{description === "Residential" ? <Residential /> : <Government /> }
<div>
</div>
</div>
</div>
</div>
);
Doing the way that you was working
function TypeImage() {
if (description === 'Residential') {
return <Residential />;
}
return <Government/>;
}
return (
<div>
<div>
<div className="hidden lg:inline-flex mb-1 px-9">
<TypeImage/>
<div>
</div>
</div>
</div>
</div>
);
Doing this another way using conditional inline
return (
<div>
<div>
<div className="hidden lg:inline-flex mb-1 px-9">
{description === "Residential" && <Residential /> }
{description === "Government" && <Government/> }
<div>
</div>
</div>
</div>
</div>
);

Related

reactJS copy to clipboard

I wonder if something like this is doable in reactjs (i'm new).
In this example, when user hovers over the email address (at the bottom), it says: copy to clipboard, once clicked, email is copied.
https://shapefarm.net/contact/
I have the styling, once hovered, the text appears, but I really don't know how to implement the functionality, any ideas? Thank you!
const Footer = () => {
return (
<>
<FooterContainer>
<FooterBg>
<div className="footer-wrapper">
<div className="info">
<div className="hovertext-container">
<p className="hovertext-p1">
mymail#test.com
</p>
<p className="hovertext-p2">copy to clipboard</p>
</div>
</div>
<div>
<SocialMedia />
</div>
</div>
</FooterBg>
</FooterContainer>
</>
)
}
export default Footer
A simple
onClick={() => {navigator.clipboard.writeText(this.state.textToCopy)}}
is going to do the job, you can also try out this npm package.
const Footer = () => {
let email = "mymail#test.com";
return (
<>
<FooterContainer>
<FooterBg>
<div className="footer-wrapper">
<div className="info">
<div className="hovertext-container">
<p className="hovertext-p1">
mymail#test.com
</p>
<p onClick={async () => {
await navigator.clipboard.writeText(email)
alert("Copied text!")
}}
className="hovertext-p2">copy to clipboard</p>
</div>
</div>
<div>
<SocialMedia />
</div>
</div>
</FooterBg>
</FooterContainer>
</>
)
}
export default Footer

Next js component doesn't show without reload

Basically, I have a nested component that I want to render with the parent component and it's working fine when the server starts.
But the problem arises when I switch back from another page. Some of the nested components get disappeared. If I made a refresh then again everything ok.
How can I solve this issue?
Normal:
Image-1
Component disappeared:
Image-2
Index.js:
import BannerBaseLine from "./../components/HOME/Banner/BannerBaseLine";
import SubSection1 from "./../components/ABOUT/subSection1";
import CoursesList from "../components/HOME/MOSTTRENDING/CoursesList/courseslist";
import ShortOverview from "./../components/HOME/CourseOverviewSection/Section1/shortoverview";
import Testimonial from "./../components/HOME/Testimonial/testimonial";
import ClientItem from "./../components/HOME/Client-area/all-client-item";
export default function HomeMain({categories}) {
return (
<>
<br></br>
<br></br>
<br></br>
<BannerBaseLine categories = {categories} />
<CoursesList />
{/* <SubSection1 /> */}
<ShortOverview />
<CoursesList />
<Testimonial />
<ClientItem />
</>
);
}
export async function getStaticProps(){
const response = await fetch('http://localhost:8000/api/data/categories')
const data = await response.json()
console.log(data)
return {
props:{
categories : data,
}
}
}
BannerBaseLine component:
import BannerBlock from './BannerBlock';
export default function BannerBaseLine({ categories }) {
return (
<>
<section
className="banner-area"
style={{ backgroundImage: "url(assets/img/banner/0.jpg)" }}
>
<div className="container">
<div className="row">
<div className="col-lg-6 col-md-8 align-self-center">
<div className="banner-inner text-md-start text-center">
<h1>
Find the Best <span>Courses</span> & Upgrade{" "}
<span>Your Skills.</span>
</h1>
<div className="banner-content">
<p>
Edufie offers professional training classes and special
features to help you improve your skills.
</p>
</div>
<div className="single-input-wrap">
<input type="text" placeholder="Search your best courses" />
<button>
<i className="fa fa-search"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</section>
<br></br>
<br></br>
<div className="container">
<div className="intro-area-2">
<div className="row justify-content-center">
<div className="col-lg-12">
<div className="intro-slider owl-carousel">
{categories.map((category) => {
return (
<>
<BannerBlock category={category} key={category.id} />
</>
);
})}
</div>
</div>
</div>
</div>
</div>
</>
);
}
BannerBlock component:
export default function BannerBlock({category}) {
console.log(category);
return (
<div className="item">
<div className="single-intro-wrap">
<div className="thumb">
<img src={category.image} alt="img" />
</div>
<div className="wrap-details">
<h6>
{category.Base_Category_Title}
</h6>
<p>236 Course Available</p>
</div>
</div>
</div>
);
}
From https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation
Note: You should not use fetch() to call an API route in
getStaticProps. Instead, directly import the logic used inside your
API route. You may need to slightly refactor your code for this
approach.
Fetching from an external API is fine!
you should check if categories exist
export default function HomeMain({categories}) {
if(categories){
return <Loading Component />
}
rest of the code...
}

How Can I change the property of components of React?

I am new to React and recently started working on it. I know that we cannot change the components properties using the props.
I want to know how can we change the properties of Component?
Below is my code:
Courses.jsx
function Courses(){
return (
<div className="courses">
<h1>Ongoing Courses</h1>
<div className="row">
{CourseData.map((value,index)=>{
return (
<div className="col-md-3">
<Card title={value.title} completed={value.completed} content={value.content} value="Resume !" key={index} id={index} />
</div>
);
})}
</div>
</div>
);
}
Here above i am having a Array of Data named as courseData, I am mapping it on a Card component.
Card.jsx:
function Card(props){
function handleClick(){
}
return (
<div className="card">
<div className="card-body">
<h2 className="card-title">{props.title}</h2>
{props.content}
<br/>
<button className="btn btn-danger" > {props.value}</button>
</div>
</div>
);
}
the CourseData has following properties :
courseData : [{
key,
title,
completed
content}]
I simply want that when ever the button present is card gets clicked then the completed attribute of courseData changed to some different value that is passed through the props .
I have tried a lot but not able to do .
Any help regarding this will be helpful for me .
courseData.jsx:
const notes = [{
key: 1,
title: "some Text",
completed:false,
content: "some Text"
},
{
key: 2,
title: "some Text",
completed:false,
content: "some Text"
}]
export default notes;
Add CourseData to the state of the Courses component. Then add a method to adjust the data there. Pass the method throught props that will be called when clicking button in the Card component:
function Courses() {
const [courseData, setCourseData] = useState(CourseData);
const updateCourseData = (index) => {
courseData.splice(index, 1);
setCourseData(courseData);
}
return (
<div className="courses">
<h1>Ongoing Courses</h1>
<div className="row">
{courseData.map((value,index)=>{
return (
<div className="col-md-3">
<Card title={value.title} updateCourseData={updateCourseData} completed={value.completed} content={value.content} value="Resume !" key={index} id={index} />
</div>
);
})}
</div>
</div>
);
}
in the Card.jsx:
<button onClick={() => props.updateCourseData(props.id)} className="btn btn-danger" > {props.value}</button>
function Courses(){
const [coursesData, setCoursesData] = useState(CourseData)
return (
<div className="courses">
<h1>Ongoing Courses</h1>
<div className="row">
{coursesData.map((value,index)=>{
return (
<div className="col-md-3">
<Card coursesData={coursesData} setCoursesData={setCoursesData} title={value.title} completed={value.completed} content={value.content} value="Resume !" key={index} id={index} />
</div>
);
})}
</div>
</div>
);
function Card({id,title,value,content,coursesData,setCoursesData }){
function handleClick(e){
e.preventDefault()
setCoursesData(coursesData => {
const data = coursesData
data.splice(id,1,{
title: title,
completed: value,
content: content,
key: id
})
return data
})
}
return (
<div className="card">
<div className="card-body">
<h2 className="card-title">{title}</h2>
{content}
<br/>
<button onClick={handleClick} className="btn btn-danger">{value}</button>
</div>
</div>
);

Cards inside the grid-container: each child in a list should have a unique "key" prop

What I`m doing wrong?It also says: "Check the render method of Card" , which is here:
<div className="grid-container">
{pokemonData.map((pokemon, i) => {
console.log(pokemon.id) // unique numbers are here
return <Card key={pokemon.id} pokemon={pokemon} />
})}
</div>
Card component itself:
function Card({ pokemon }) {
return (
<div className="card">
<div className="card__image">
<img src={pokemon.sprites.front_default} alt="Pokemon" />
</div>
<div className="card__name">
{pokemon.name}
</div>
<div className="card__types">
{
pokemon.types.map(type => {
return (
<div className="card__type" style={{backgroundColor: typeColors[type.type.name]}}>
{type.type.name}
</div>
)
})
}
</div>
<div className="card__info">
<div className="card__data card__data--weight">
<p className="title">Weight:</p>
<p>{pokemon.weight}</p>
</div>
<div className="card__data card__data--height">
<p className="title">Height:</p>
<p>{pokemon.height}</p>
</div>
<div className="card__data card__data--ability">
<p className="title">Abilities:</p>
{/* {console.log(pokemon.abilities)} Temporary for dev puprose */}
{pokemon.abilities.map(ability => <p>{ability.ability.name}</p>
)}
</div>
</div>
</div>
);
}
export default Card;
You can use the index of the array may be your data is having some kind of duplicate. It is recommended that you pass a key prop whenever you are returning a list.
<div className="grid-container">
{pokemonData.map((pokemon, i) => {
console.log(pokemon.id) // unique numbers are here
return <Card key={i} pokemon={pokemon} />
})}
</div>
Equally, check this segment of card components.
{
pokemon.types.map((type,i) => {
return (
<div key={i} className="card__type" style={{backgroundColor:
typeColors[type.type.name]}}>
{type.type.name}
/div>
)
})
}
And
<div className="card__data card__data--ability">
<p className="title">Abilities:</p>
{/* {console.log(pokemon.abilities)} }
{pokemon.abilities.map((ability, i) => <p key={i}>{ability.ability.name}
</p>
)}
</div>
Previous answer will solve your problem. However, for your info, I would also like to add here.
For React a key attribute is like an identity of a node/element/tag which helps React to identify each item in the list and apply reconciliation correctlyon each item. Without a key React will render your component but may cause issue when you re-order your list.
React recommends to use id of the data instead of index number. However, if your list does not re-orders/ sorts or do not have id then you can use index.
You can read more here:
https://reactjs.org/docs/lists-and-keys.html
Change this:
<div className="card__types">
{
pokemon.types.map(type => {
return (
<div className="card__type"
style={{backgroundColor:typeColors[type.type.name]}}
>
{type.type.name}
</div>
)
})
}
</div>
to:
<div className="card__types">
{
pokemon.types.map((type, key) => {
return (
<div key={key} className="card__type"
style={{backgroundColor:typeColors[type.type.name]}}
>
{type.type.name}
</div>
)
})
}
</div>
and:
{pokemon.abilities.map(ability => <p>{ability.ability.name}</p>
to:
{pokemon.abilities.map((ability,key) => <p key={key} >{ability.ability.name}</p>

In React how do I use a conditional with rendering?

I have a simple notification window, and as notifications are accepted/declined I remove the object from the notifications array.
This is my bit of code for handling displaying messages:
render: function() {
return (
<div className="chatwindowheight">
<div className="row">
<div className="large-12 columns">
<div className="large-8 columns">
<p className="thin partyHeader">Party <i className="fa fa-minus-square-o"></i></p>
</div>
<div className="large-4 columns">
<i className="fa fa-users pull-right"></i>
</div>
</div>
</div>
<div className="row chatwindowheight">
<div className="large-12 small-12 columns chatwindow" id="scrolldown">
<br/>
{
this.state.messages.map((message, i) => {
return (
<MessageComponent key={i}
username={message.username}
message={message.message}
whos={message.classed} />
);
})
}
</div>
</div>
<ChatSendComponent onChatSubmit={this.handleChatSubmit}/>
</div>
)
}
What I want is to have something like
if (this.state.messages.length === 0) {
return (
<p>You have no new notifications.</p>
)
}
but when I try to wrap something like that around the current loop, it tells me that if is an error. New to React so just trying to understand the best method for approaching this. Thanks!
There are some various resolve your problem:
1.
{ this.state.messages.length > 0 ?
this.state.messages.map((message, i) => {
return (
<MessageComponent key={i}
username={message.username}
message={message.message}
whos={message.classed} />
);
}) : 'You have messages'
}
Remove you map up to render function and prepare your data there:
function render() {
var message='';
if (this.state.messages.length) {
}
}
<b>{message}</b>

Categories

Resources