Render react icon based on comparison with array - javascript

I currently have the following array with data:
const colors = {
Meeting: ["#D09FE8", GrGroup],
"1on1": ["#86DB43", MdLocalLibrary],
Review: ["#B22F5E", MdRateReview],
"Team Collaboration": ["#B22F5E", RiStackshareFill],
"Feature Review": ["#B22F5E", MdFeaturedPlayList],
};
My react component is receiving a prop which contains a string of the meeting type, for example "Meeting". Based on that prop, i want to render a react icon.
Changing the background color is fine, I just did it as follows:
const style = {
background: colors[`${eventData.meetingType}`][0],
}
But when trying to render the react icon, how can i do that here?
<div className="text-sm">{RENDER THE REACT ICON HERE}</div>

You can conditionally render components using conditional rendering:
<div className="text-sm">
{/* Think of this as an if statement. */}
{ (meetingType === something) && (
<img src={iconASrc} />
)}
{/* Conversely, this is an if-else statement. */}
{ (meetingType === something) ? (
<img src={iconASrc} />
) : (
<img src={iconBSrc} />
)}
{/* Or, even better */}
<img src={(meetingType === something) ? iconASrc : iconBSrc} />
</div>
See ternary operator for the latter two options.

Related

Objects are not valid as a React child (found: object with keys {Dname, recipe_diet}). If you meant to render a collection of children, use an array

I can get all my api info, but when create a new "recipe" and I try to show it on the Front, I get that error, but just on the "recipe" that I created, :c
import React from "react";
import './estilos/Cartita.css'
export default function Card({image, title, diets, healthScore, createdInBd, id}){
return (
<div className="containerr">
<div className="card">
<h2>{id}</h2>
<img src={image} alt="img not found" width="200px" height="250px"/>
<h2>NOMBRE:</h2>
<h5>{title}</h5>
<p>Tipo de dieta</p>
<div >
{
(!diets.length)?
<span>This Recipe doesnt have a diet
</span> :
diets.map((diet) => (
<span><li key={diets}> {diet}</li></span>
)
)}
</div>
<h2>HEALTSCORE:</h2>
<h5>{healthScore}</h5>
<h5>{createdInBd}</h5>
</div>
</div>
);
}
and this is the Api info, the top one is from the api and the other one is the one that I created:
enter image description here
due to your screenshot diets can be array of strings or array of objects, therefore you need to check if diet is an object
{!diets.length ?
<span>This Recipe doesnt have a diet</span> :
diets.map((diet) => (
<span><li key={diet.id}>{typeof diet === 'string' ? diet : diet.Dname}</li></span>
)
)}

I don't know how to change the status of a modal

Good morning, I am in a React and JS project and I am still learning React and some things are difficult to do and I have a small problem with which I can't make any progress.
I had a modal with one color for all the results, but I have been told that depending on the result it is necessary to show one color or another. I have it defined this way in the Modal component:
const headerModal = {
0: "modal-error", //red
1: "modal-ok", //green
};
And in another component I have what would go inside the kata, everything that has the className "statusKata" should come out with headerModal={1} and the "Not started" with headerModal={0} but I don't know how to implement it, that code is this below:
import React from 'react';
const DetailUserKata = (props) => {
return (
<>
{!props.statusKata ?
<div>Obteniendo datos...</div> :
props.statusKata.length ?
<div>
<div className="statusKata"><label>Autor: </label> {props.statusKata[0].author_login_txt}</div>
<div className="statusKata"><label>Cuenta de GitHub: </label> {props.statusKata[0].autor_github_url}</div>
</div> :
<div>Not started</div>
}
</>
);
}
export default DetailUserKata;
At first, in the page where the modal is shown I had it as below with the header={1} with the green color (modal-ok), but I have to change it:
<Modal show={showKata} handleClose={hideModalKata} header={1} title="Detalles de la kata">
{<DetailUserKata statusKata={detail} />}
</Modal >
Thanks in advance! And any feedback for change or help is always welcome.
Replace green and red with your desired colors
import React from 'react';
const DetailUserKata = (props) => {
return (
<div style={{background-color: props.header === headerModal[1] ? 'green' :
props.header === headerModal[0] ? 'red' :''}
}>
{!props.statusKata ?
<div>Obteniendo datos...</div> :
props.statusKata.length ?
<div>
<div className="statusKata"><label>Autor: </label> {props.statusKata[0].author_login_txt}</div>
<div className="statusKata"><label>Cuenta de GitHub: </label> {props.statusKata[0].autor_github_url}</div>
</div> :
<div>Not started</div>
}
<div/>
);
}
export default DetailUserKata;
and move header prop to DetailUserKata
<Modal show={showKata} handleClose={hideModalKata} title="Detalles de la kata">
{<DetailUserKata statusKata={detail} header={headerModal[1]} />}
</Modal >

Use props from component in another file

As you might understand, I'm pretty new to React. I tried to search StackOverflow and google this, but I cannot find anything that answers this question.
I'm creating this travel review page. I save a form to a Firebase database and I display it using a component. However, I want to display, say, only the name of a country, but I cannot manage to do that. I'm pretty sure that I must pass it as a prop but I cannot figure out how to do that, exactly.
What I want is to, use this component and decide in the component what to view.
If I'd use this component in some other .js-file, I'd like to do something like this:
and display only the data that lies withing the field countryName.I'm going to use the country names as a list, that's why I want to single out just the names.
I've played around using props but I cannot get my head around it. Perhaps someone could help out?
Thanks.
This is the function which I use as a component:
const CountryList = () => {
const countries = useCountries()
return (
<div className="countries">
{countries.map((country) =>
<div key={country.id}>
<div className="time-entry">
Name of review: {country.revName} <br/>
Name of Country: {country.countryName}<br/>
Destination 1: {country.dest1}<br/>
Destination 2: {country.dest2}<br/>
Destination 3: {country.dest3}<br/>
Beer price: {country.beerPrice}<br/>
Food price: {country.foodPrice}<br/>
Hostel price: {country.hostelPrice}<br/>
Review: {country.review}<br />
<img src={country.url} alt="no-img" />
</div>
</div>
)}
</div>
)
}
Super simple way could be to pass an array of "fields" you want to display as a prop, and conditionally render UI. If the displayFields array includes the name of the country property then render that "field".
Example:
const CountryList = ({ displayFields = [] }) => {
const countries = useCountries();
return (
<div className="countries">
{countries.map(country => (
<div key={country.id}>
<div className="time-entry">
{displayFields.includes("revName") && (
<div>Name of review: {country.revName}</div>
)}
{displayFields.includes("countryName") && (
<div>Name of Country: {country.countryName}</div>
)}
{displayFields.includes("dest1") && (
<div>Destination 1: {country.dest1}</div>
)}
{displayFields.includes("dest2") && (
<div>Destination 1: {country.dest2}</div>
)}
{displayFields.includes("dest3") && (
<div>Destination 1: {country.dest3}</div>
)}
{displayFields.includes("beerPrice") && (
<div>Beer price: {country.beerPrice}</div>
)}
{displayFields.includes("foodPrice") && (
<div>Food price: {country.foodPrice}</div>
)}
{displayFields.includes("hostelPrice") && (
<div>Hostel price: {country.hostelPrice}</div>
)}
{displayFields.includes("review") && <div>Review: {country.review}</div>}
{displayFields.includes("imgUrl") && <img src={country.url} alt="no-img" />}
</div>
</div>
))}
</div>
);
};
Usage:
<CountryList displayFields={["countryName", "beerPrice"]} />

How to pass ref to component in React?

I am using a library called react-swipe (not especially relevant), which exposes next() and prev() methods on the instance, which I am accessing through a ref.
When I have the ReactSwipe component in my main App.js file this works perfectly well, e.g.:
_handlePrev() {
this.reactSwipe.prev()
}
_handleNext() {
this.reactSwipe.next()
}
render() {
let singlePlanets
singlePlanets = this.state.planetData.map(data => {
return (
<div className="single-planet" key={data.id}>
<div className="image">
<img src={emptyPlanet} alt={data.name} />
</div>
<h2>{data.name}</h2>
<div className="extract" dangerouslySetInnerHTML={{ __html: data.extract }} />
</div>
)
})
return (
<div className="app-container">
<TitleBar />
<ReactSwipe ref={reactSwipe => this.reactSwipe = reactSwipe} className="content" key={singlePlanets.length}>
{singlePlanets}
</ReactSwipe>
<MenuBar handleNext={this._handleNext.bind(this)} handlePrev={this._handlePrev.bind(this)} />
</div>
)
}
But what I'm trying to do is separate out the ReactSwipe and planetData mapping logic into its own component (code below), however when I do this (by trying to pass the ref through as a prop) I always get the error this.reactSwipe.prev() (or .next()) is not a function, no matter what I try. I'm wondering - what is the correct way to go about this?
This what I have in my return in App.js:
<PlanetInfo planetData={this.state.planetData} swipeRef={reactSwipe => this.reactSwipe = reactSwipe} />
and in PlanetInfo component:
return (
<ReactSwipe ref={this.swipeRef} className="content" key={singlePlanets.length}>
{singlePlanets}
</ReactSwipe>
)
Replace ref={this.swipeRef} with ref={this.props.swipeRef} in PlanetInfo component.

ReactJS if prop exists

at the moment I am getting an error with React because I am mapping an array of objects from a REST end point and some of the objects in the array don't have certain props.
An example is that some of my objects have another object within them called imagesand some don't. When my React component tries to render the objects without the images I am left with an error undefined prop.
Here is my component that renders my prop:
const VehicleDetail = (props) => {
return (
<div className={"col-flex-md-3 col-flex-sm-4 col-flex-xs-6 col-flex-media-query vehicle-item " + props.vehicle.brand.name} data-value={props.vehicle.brand.name}>
<div className="vehicle-container">
<img src={"https://s3-eu-west-1.amazonaws.com/pulman-vw-images/uploads/images/thumbnails/" + props.vehicle.offers[0].image.name} />
<h4 className="vehicle-title">
{props.vehicle.model.name}
</h4>
<div className="row-flex">
<div className="col-flex-xs-12 btn-container">
Learn More
</div>
</div>
</div>
</div>
);
};
So as you can see I have an img element with a prop of props.vehicle.offers[0].image.name however this fails as some of my objects don't have this object available.
So far I have tried adding an inline conditional just to see if the object existed first however this failed with an error:
<img src={"https://s3-eu-west-1.amazonaws.com/pulman-vw-images/uploads/images/thumbnails/" + {if (typeof props.vehicle.offers[0].image.name == "object") { props.vehicle.offers[0].image.name }}} />
Here is my component that iterates over each object and renders them to my VehicleDetail component:
// Vehicle List Component
import VehicleDetail from './vehicle-detail.js';
// Create our component
const VehicleList = (props) => {
// Just add props.vehicle to access API data instead of static
const RenderedVehicles = props.vehicles.map(vehicle =>
<VehicleDetail key={vehicle.slug} vehicle={vehicle} />
);
return (
<div className="row-flex center-xs">
{RenderedVehicles}
{console.log(props.brandSelect)}
</div>
);
};
Any idea what the best practice in React JS is to do this? Thanks
Check the length of offers before rendering.
{props.vehicle.offers.length > 0 ? (
<img src={url + props.vehicle.offers[0].image.name} />
) : null}
I'd do it like this. In your vehicle component declare a variable that would hold the thumbnail url.
const VehicleDetail = (props) => {
let vehicleThumbnail = '';
if (props.vehicle.offers[0].image && props.vehicle.offers[0].image.name) {
vehicleThumbnail = props.vehicle.offers[0].image.name;
}
return (
<div className={"col-flex-md-3 col-flex-sm-4 col-flex-xs-6 col-flex-media-query vehicle-item " + props.vehicle.brand.name} data-value={props.vehicle.brand.name}>
<div className="vehicle-container">
<img src={vehicleThumbnail} />
<h4 className="vehicle-title">
{props.vehicle.model.name}
</h4>
<div className="row-flex">
<div className="col-flex-xs-12 btn-container">
Learn More
</div>
</div>
</div>
</div>
);
};
I'd also do the same for the other props.
The normal case of props.vehicle.offers[0] may looks like this:
{
image: {
name: 'hello'
}
}
So, you can use props.vehicle.offers[0].image.name without any error.
But some cases are:
{
anotherProperty: {
}
}
props.vehicle.offers[0].image is null, so props.vehicle.offers[0].image.name equals to null.name, which throw the error.
A simple way to solve the problem is something like this:
{ props.vehicle.offers[0].image && <img src={"https://s3-eu-west-1.amazonaws.com/pulman-vw-images/uploads/images/thumbnails/" + props.vehicle.offers[0].image.name} /> }
If props.vehicle.offers[0].image is null, the statement after && will not be execute, and return nothing to render.
So, it render img element when props.vehicle.offers[0].image is not null, preventing the error.

Categories

Resources