React conditionally show link if there is content on json file? - javascript

Did some searching around, but could not find anything. this is something simple on jQuery and Rails, but not sure if there is a correct way to to this in React. I have this component that is grabbing its data form a JSON file, and I want to only display a certain link if the JSON has content, otherwise I want to hide it. I tried this way so far with no luck:
renderList(projectLinks){
//let self = this;
return projectLinks.map(function(link) {
var showDemo = "";
if(link.urlDemo === ""){
console.log("i'm empty");
showDemo = "displayNone";
}
return <Panel header={link.title} eventKey={link.eventKey} key={link.title}>
<p>{link.description}</p>
<img src={link.image} className="img-thumbnail" alt="project thumbnail"/><br />
<a href={link.urlDemo} className={showDemo}>Demo </a>
<a href={link.urlCode}>Code </a>
</Panel>
});
}
so, if the json link is empty like this: "urlDemo": "", I want the link to be hidden.
Appreciate the help.

Inside render, use conditional operator. Here's an example
render(){
return (
<div>
{this.state.check ? <div>Show this if check is true</div> :
<div>Show this if check is false</div>}
<div>
)
}
Edit: A more specific example
render(){
return(
<div>
{link.urlDemo ? <a href={link.urlDemo}>Demo </a> : null}
</div>
)
}
Another way of doing the same:
render(){
return(
<div>
{link.urlDemo && <a href={link.urlDemo}>Demo </a>}
</div>
)
}

Related

There is a problem with implementing the map function of react

I'm sorry to ask you a simple question first. But I don't know where to fix it. I wanted to create an array of characters like a picture, so I used the map function and array, but I can't apply which part of the code is wrong. Can I know which part is wrong and how to change it? Thanks.
Footer.jsx:
this is the file I used map function and array
const array = [
'Meta', '소개', '블로그', '채용 정보', '도움말', 'API', '개인정보처리방침', '약관', '인기 계정', '해시태그', '위치', 'Instagram Lite', '연락처 업로드 & 비사용자'
]
function Footer() {
return (
<FooterWrap>
<div className='FooterWrap2'>
<div className='FooterContent1'>
<div className='FooterContent1Wrap'>
{array.map((text, idx) => {
return (
<div>
<a>
<div>
{text}
</div>
</a>
</div>
)
})}
</div>
</div>
<div className='FooterContent2'>
</div>
</div>
</FooterWrap>
)
}
export default Footer;
Why not just use a tag and its href pointing to it's link
{array.map((text, idx) => {
return (
<a href="add_url_here" key={text}>
{text}
</a>
)
})}
If you have styling issues, you can add a codesandbox link, save code and share so one can look in to it

Why is an array that is passed correctly via props returning undefined?

I'm trying to load each string of an array of strings in a <li> html tag by passing this array via props:
<CardItem
src='https://static.news...koinex-banner.png'
text='my text'
label='Adventure'
path='/products'
description={["someText1", "someText2", "someText3", "someText4"]}
/>
function CardItem(props) {
return (
<>
<li className='cards__item'>
<Link className='cards__item__link' to={props.path}>
<figure className='cards__item__pic-wrap' data-category={props.label}>
<img
className='cards__item__img'
alt='Travel Image'
src={props.src}
/>
</figure>
<div className='cards__item__info'>
<h5 className='cards__item__text'>{props.text}</h5>
</div>
<CardDescription description={props.description} />
</Link>
</li>
</>
);
}
export default CardItem;
function CardDescription(props) {
return (
<div>
<ul>
<li>{props.description[0]} </li>
</ul>
</div>
)
}
export default CardDescription
And I'm getting
TypeError: Cannot read properties of undefined (reading '0')
I'm not sure why props.description prop is returning undefined.
Also, this TypeError seems to only be happening with the props.description prop.
Your code is misspelled CardDescrition to CardDescription
Try:
{props.description ? <CardDescription description={props.description} /> : ''}
and in description:
function CardDescription(props) {
return (
<div>
<ul>
{props.description.map(des => <li>des</li>)}
</ul>
</div>
)
}
please find the minimal repo I created:
https://github.com/snake-py/so-help-react-card
Explanation:
I try to explain from what I understand what is happening there.
When Carditems mounts it seems even though you hard code the values, that they are not passed on the initial render. Hence, the ternary check if the props include the description array.
I am guessing now why that is:
Perhaps because they are inside a wrapper component of Link. If you remove the Link component the code should work without the initial check.
well, that's probably because during the mounting of the three the description prop could be undefined, you could avoid this error by doing this props?.description[0], also if you want to render all the values in the array inside the CardDescrition component you could do this
props?.description.map((item) => (<li>{item}</li>))

How to display data according to query string using ReactJs?

I have multiple data & I want to display data as per query string, how can I do that in reactJs?
My code:
const Ladies = () => {
return (
<div>
if('http://localhost:3000/ladies?service=makeup'){
<div>Makeup Content</div>
}
else('http://localhost:3000/ladies?service=hairStyling'){
<div>Hair Styling Content</div>
}
</div>
)
}
Thank You!
I consider this for your url
http://localhost:3000/ladies?service=makeup
In your code
const params = new URLSearchParams(window.location.search)
check if it has the query
params.has('service')?params.get('service'):""
or log it
console.log(params.has('service')?params.get('service'):"")
return will be makeup
I'm not sure but i think it will be string so if you want to use it check if it's equal to "makeup" like so
<div> {params.has('service')&&params.get('service')==="makeup"?"There is makeup":"There is no make up in query strings !"}</div>
Update:
you can put that just like a text to show a div instead, that is a great feature of jsx, do it like this.
<div>
{params.has("service") && params.get("service") === "makeup" ? (
<div>Makeup section</div>
) : params.get("service") === "hairStyling" ? (
<div>hair styling section</div>
) : (
<div>cannot find any query strings</div>
)}
</div>
For more info check out here

Is it possible to align a div based on a condition?

I have a div which I have set to align="right". I have created a local variable called userId and assigned 1 to it and I am wondering if is possible to somehow set the div to left align if userId === 1, which will be the case. I've tried reading the react docs on conditional rendering but I don' believe that is what I'm looking for as they all deal with rendering whereas the div that I want to align is being returned by an export function so the render function isn't used.
export function MessageRow({ message, fetch }) {
return (
<div>
<br />
<div align="right" className="Message-Body">
<div className="Message-row-header">{message.user}</div>
<div>{message.content}</div>
<div className="muted-text">
(Sent: {new Date(message.timestamp).toUTCString()})
</div>
<div>
<button
className="block"
onClick={() => messageService.delete(message.id).then(fetch)}
>
Delete
</button>
<button className="block">Edit</button>
</div>
</div>
</div>
);
}
This is what I currently have and was thinking of trying a function like below but I am unsure how I would then get it to apply to the div.
function checkMessageUserID(userId) {
if (userId === 1) {
}
}
It is still being used from a render() point of view though, no?
So you could still do what you want:
return (
<div><br />
{userId !== 1 ?
<div align="right" className="Message-Body">
:
<div align="left" className="Message-Body">
}
...
1) You can return JSX from the function and call the function inside return.
function checkMessageUserID(userId) {
if (userId === 1) {
<div align="right" className="Message-Body">
}
else{
<div align="left" className="Message-Body">
}
}
Then inside return call {checkMessageUserID()}
2) You can also use ternary operator inside your render.
<div align = {userID == 1 ? "right" : "left"} className="Message-Body">
Conditional rendering works the same for functional as well as stateful components.
Working code snippet below.
<div align={userId === 1 ? 'left' : 'right' } className="Message-Body">
You could do any of the above, or what I would recommend is, you create two styling classnames, you can call them 'left/right-message' or 'mine/otherPerson-message' and you can assign align: 'left/right' to each, you can even assign different colors for that chat feel, you'd achieve this simply by doing:
<div className={userId === 1 ? "left-message" : "right-message" >
...
</div>

Render a component within another in React

When a state is changed, React triggers componentDidUpdate() method, and by then I do:
componentDidUpdate: function () {
React.render(new SubmitButton, $('.uploader-submit').get(0));
}
As you saw, I'm rendering a SubmitButton when a specific state is changed, but my question is: is this the best behavior to get this feature done?
My scenario is: I'm uploading a photo. When the input[type=file] is changed, I create a new state property and then the componentDidUpdate() is triggered, invoking the SubmitButton.
This is my render() method:
render: function () {
return (
<div className="uploader">
<header className="uploader-header">
<div className="uploader-actions pull-left">
<div className="uploader-submit"></div>
<CancelButton router={this.props.router} />
</div>
<UploadButton callback={this.imageSelectedCallback} />
</header>
<Preview imageUri={this.state.imageUri} />
</div>
)
}
Couldn't I do something like the <Preview /> component? I mean, it is there, but something just appears when this.state.imageUri is different of null. This is the implementation of Preview:
var Preview = {
render: function () {
return (
<img src={this.props.imageUri} />
)
}
};
module.exports = React.createClass(Preview);
Yes, I know — "Preview" is invisible by default because it is an image, but I want to know if there's another approach to reach what I want: to show something based on a state, using the render method.
React doesn't render falsy values, be it a component or an attribute (like in the Preview case), e.g.
<div>{null}</div>
<img src={null} />
renders to
<div></div>
<img/>
So typically you just create a variable and conditionally assign it a component or null as was also suggested in another answer:
var button = null;
if(myConditionForShowingButton) {
button = <SubmitButton />;
}
-- or simply --
var button = myConditionForShowingButton ?
<SubmitButton /> :
null;
In cases where the component gets bigger it's typically more readable and cleaner to have a subroutine for rendering that part
var complexComponent = condition ?
this.renderComplexComponent() :
null
Yes. If-Else in JSX.
render: function () {
var submitButton;
if (this.state.imageSelected)
submitButton = <SubmitButton />;
return (
<div className="uploader">
<header className="uploader-header">
<div className="uploader-actions pull-left">
<div className="uploader-submit">{ submitButton }</div>
<CancelButton router={this.props.router} />
</div>
<UploadButton callback={this.imageSelectedCallback} />
</header>
<Preview imageUri={this.state.imageUri} />
</div>
)
}

Categories