Hide entire parent element if child is null React - reactjs

I am new to React, I want to hide parent div if child is having null, li data is passing with props
import React from 'react';
const PublicationTags = (props) => {
return (
<div className="publication-tags">
<h4>Темы публикации</h4>
<ul>
{props.data &&
props.data.tag_names &&
props.data.tag_names.map((tag_name, key) => (
<li key={key}>
{tag_name}
</li>
))}
</ul>
</div>
);
};
export default PublicationTags;
If there is no data on li items I want to hide the and tag.

<ParentDiv style={this.props.data===null ? {display:'none'}:{display:'flex'}>{this.props.data}</ParentDiv>
Hope this helps.

Depends on the whole structure of the app but you could do something like:
import React from 'react';
const PublicationTags = props => {
if (!props.data.length) {
return null;
}
return (
<div className="publication-tags">
<h4>Темы публикации</h4>
<ul>
{props.data &&
props.data.tag_names &&
props.data.tag_names.map((tag_name, key) => (
<li key={key}>
{tag_name}
</li>
))}
</ul>
</div>
);
};
export default PublicationTags;
or:
import React from 'react';
const PublicationTags = props => {
return props.data.length ? (
<div className="publication-tags">
<h4>Темы публикации</h4>
<ul>
{props.data &&
props.data.tag_names &&
props.data.tag_names.map((tag_name, key) => (
<li key={key}>
{tag_name}
</li>
))}
</ul>
</div>
) : null;
};
export default PublicationTags;

Related

React render instagram feeds and loop comments/likes

I"m trying to render comments with likes and loop them. please see image on demo.
All of this comes form data.json
How can I loop all comments? I have only one displayed. What am I missing here?
Sorry I'm trying my best here with react as I'm quite a beginner.
my index.js
import React from "react";
import styles from "./styles";
const Posts = (props) => {
const { data } = props;
const comments = data.edge_media_to_comment.edges[0].node.text
const locationName = data.location.name
const username = data.owner.username
const id = data.id
const url = `https://www.instagram.com/${data.owner.username}`
const likes = data.edge_media_preview_like.count
return (
<>
<a href={url} rel="noopener noreferrer" target="_blank" key={id}>
<img src={data.owner.profile_pic_url} />
</a>
<span>{locationName}</span>
<a href={url} rel="noopener noreferrer" target="_blank" key={id}>#{username}</a>
<p>{username}</p>
<hr />
<ul>
<li>
{comments !== null ? comments.toLocaleString() : 0}
</li>
<li className="post-item-likes">
{likes !== null ? likes.toLocaleString() : 0}
</li>
</ul>
<hr />
</>
);
};
export default Posts;
In your Post component need to use data.comments from props and use .map
method for render multiple comments instead of comments.toLocaleString()
Example:
import React from "react";
const Posts = (props) => {
const { data } = props;
console.log('007',data);
return (
<>
<img src={data.owner.profile_pic_url} />
<span>{data.location.name}</span>
<a href="" target="_blank">
#{data.owner.username}
</a>
<p> {data.owner.username}</p>
<hr />
<div>
{data?.comments?.map(comment => {
return (<div>
{comment?.text} - {comment?.likeCount}
</div>)
})}
</div>
</>
);
};
export default Posts;
You need to map through the comments array and for each comment return the text and likes.
Declare comments - below const { data } = props;:
const comments = data.comments;
In return add this:
<ul>
{comments.map((comment) => (
<li>
{comment.text} - {comment.likeCount}
</li>
))}
</ul>

TypeError: Cannot read property 'map' of undefined" React

I am new in React , I was following the course of React. And the code as follow appeared issue like "TypeError: Cannot read property 'map' of undefined"; Can anyone tell what's going on ? Thank you so much!
import React, { Component } from 'react'
const ListGroup = props => {
const {items,textProperty,valueProperty} = props;
return (
<ul className="list-group">
{items.map(item =>(
<li key={item[valueProperty]} className="list-group-item">
{item[textProperty]}
</li>
))}
</ul>
);
}
export default ListGroup;
You didn't seem to pass items prop to ListGroup:
<ListGroup items=[] />
Alternatively, you can assign a default value to items:
const {items = [],textProperty,valueProperty} = props;
Or use elvis operator:
items?.map(item => {})
Your items object is undefined at the start. Just add a null check:
const ListGroup = props => {
const {items,textProperty,valueProperty} = props;
return (
<ul className="list-group">
{items && items.map(item =>(
<li key={item[valueProperty]} className="list-group-item">
{item[textProperty]}
</li>
))}
</ul>
);
}
You can use operate chaining, change your code to:
const ListGroup = props => {
const {items,textProperty,valueProperty} = props;
return (
<ul className="list-group">
{ items?.map(item =>(
<li key={item[valueProperty]} className="list-group-item">
{item[textProperty]}
</li>
))}
</ul>
);
}
```
I'm taking the same course. Make sure that you have passed the right props to ListGroup in Movies class just like that:
<ListGroup
items={this.state.genres}
textProperty="name"
valueProperty="_id"
onItemSelect={this.handleGenreSelect}
/>
Regards!

React Each child in a list should have a unique "key" prop. even if the key is present

I have the following react component where I set the keys on render with uuid but still getting the warning index.js:1 Warning: Each child in a list should have a unique "key" prop.
import React, { useEffect, useState } from "react";
import { v4 as uuidv4 } from "uuid";
const Breadcrumbs = (props) => {
const { path, lang } = props;
const [breadcrumbsItems, setBreadcrumbsItems] = useState(null);
useEffect(() => {
if (path) {
const content = path.map((item, index) => {
if (!item.text) return null;
const isLast = index + 1 === path.length ? true : false;
return (
<>
{isLast ? (
<span key={uuidv4()} className={"post post-jobs current-item"}>
{item.text}
</span>
) : (
<span key={uuidv4()} property="itemListElement" typeof="ListItem">
<a
property="item"
typeof="WebPage"
title={item.title}
href="/"
className="home"
>
<span property="name">{item.text}</span>
</a>
</span>
)}
</>
);
});
setBreadcrumbsItems(content);
}
}, [path]);
return (
<div key={uuidv4()}>
{breadcrumbsItems ? (
<div className="breadcrumbs uk-visible#m">
{breadcrumbsItems && breadcrumbsItems}
</div>
) : null}
</div>
);
};
export default Breadcrumbs;
What is wrong in this case with my code?
I think this is because the main child is your Fragment (<>).
You have to provide the key property to the main element you return from your map function.
Try to change your return to something like this:
<Fragment key={uuidv4()}>
{isLast ? (
<span className={"post post-jobs current-item"}>
{item.text}
</span>
) : (
<span property="itemListElement" typeof="ListItem">
<a
property="item"
typeof="WebPage"
title={item.title}
href="/"
className="home"
>
<span property="name">{item.text}</span>
</a>
</span>
)}
</Fragment>
And do not forget to import Fragment from react:
import { Fragment } from 'react';

can't use the Refs properly in react js, Cannot read property of undefined

I am very new to react and js,
I have a menu and submenu, I use a list to map data,
I want to write a function, so onmouseover one item in the list,
if it has submenu, it will show.
the problem is that I can't select the submenu using ref.
It is just too complicated for me, any help would be much appreciated!
enter image description here
import React, { Component } from "react";
export class Menu extends Component {
constructor(props) {
super(props);
this.liRefs = [];
}
showSubmenu = (e) => {
// this.liRefs.current.style.display = "block";
for (var i = 0; i < this.liRefs.length; i++) {
this.liRefs[i].current.style.display = "block";
}
// console.log(this.liRefs[10]);
};
getStyle = (e) => {
e.target.style.background = "red";
};
render() {
return (
<ul className="mainmenu">
{this.props.items.map((i) =>
i.subitems ? (
<li key={i.id} onMouseOver={this.showSubmenu}>
{i.icon}
{i.name}
<ul key={i.id} ref={(ref) => (this.liRefs[i.id] = ref)}>
{i.subitems.map((item) => (
<div key={item.id} className="submenu">
{item.icon}
{item.name}
</div>
))}
</ul>
</li>
) : (
<li key={i.id}>
{i.icon}
{i.name}
{i.img}
</li>
)
)}
</ul>
);
}
}
export default Menu;
You are giving ref value to this. liRefs[i.id] and accessing through this. liRefs[i] so that both are the different change your code as below:
{this.props.items.map((i,index) =>
i.subitems ? (
<li key={i.id} onMouseOver={this.showSubmenu}>
{i.icon}
{i.name}
<ul key={i.id} ref={(ref) => (this.liRefs[i.id] = ref)}>
{i.subitems.map((item) => (
<div key={item.id} className="submenu">
{item.icon}
{item.name}
</div>
))}
</ul>
</li>
) : (
<li key={i.id}>
{i.icon}
{i.name}
{i.img}
</li>
)
)}

convert React-Js function to class

I tried to convert react js function to class but I didn't know how to convert it completely please look at this function and convert it for me correctly.
original function
code :var MailboxList = React.createClass({render: function() {
var mailbox_list = this.props.mailboxes.map(function(mailbox) {
return (
<li className="list-group-item"
key={mailbox.id}
onClick={this.props.onSelectMailbox.bind(null, mailbox.id)}>
<span className="badge">
{mailbox.emails.length}
</span>{mailbox.name}</li>);}.bind(this));
return (
<divclassName="col-md-2">
<ul className="mailboxes list-group">
{mailbox_list}</ul>
</div>);
}});
I would recommend using the most recent way to build component with babel 6.
As a Functions
export default function MailboxList({ mailboxes }) {
const mailbox_list = mailboxes.map((mailbox) =>
(
<li className="list-group-item"
key={mailbox.id}
onClick={this.props.onSelectMailbox.bind(null, mailbox.id)}
>
<span className="badge">
{mailbox.emails.length}
</span>{mailbox.name}</li>
));
return (
<div className="col-md-2" >
<ul className="mailboxes list-group">
{mailbox_list}</ul>
</div>
);
}
As a Class
export default class MailboxList extends React.Component {
renderMailboxList = () => {
return (
this.props.mailboxes.map((mailbox) => (
<li className="list-group-item"
key={mailbox.id}
onClick={this.props.onSelectMailbox.bind(null, mailbox.id)}
>
<span className="badge">
{mailbox.emails.length}
</span>
{mailbox.name}
</li>
))
)
}
render() {
return (
<div className="col-md-2" >
<ul className="mailboxes list-group">
{this.renderMailboxList}</ul>
</div>
);
}
}

Resources