How to handle change of onClick on dropdown menu in react.js - javascript

I need your advice and suggest, I have here a react app that has three main component: search bar, cards, and filters. In the filters I have a drop down menu that contain at least 11 vlaues. so what I want that I create function that handle the change when I onclick one of the values and search for it.
I face two problems:
how to create on handle function for 11 elements
how to search for it after one click, because I try to test with one element and change after two clicks
The code:
//Function to create the cards with their property values
function CreateCards(doc) {
return (
<SimpleCard
key={doc.id}
theCardId={doc.id}
cardType={doc.approvetool}
cardNum={doc.num}
cardName={doc.name}
cardDate={format(new Date(doc.date), "dd/MM/yyyy")} // casting the system date to arabic date
// cardCategory={NCARMap.cardCategory}
// cardSource={NCARMap.cardSource}
cardDesc={doc.summary}
cardURL={doc.image}
/>
);
}
//create the class
export default class OfficialDocument extends Component {
//constructor elements
constructor(props) {
super(props);
//initially no data entered
this.state = {
NCARMap: [], // for print cards and changeable
NCARMapAS: [], // for print cards and unchangeable (Default value always)
search_query: "", // store the query word
search_query_drop: "", // to store the query word of drop down menu
noPlaceFound: false, // condition to print message when no result up
size_query: 0, // for set the size or number of docs to return
highlight: "",
};
this.handleChange = this.handleChange.bind(this);
this.DropDownChangeOne = this.DropDownChangeOne.bind(this);
}
componentDidMount() {
//Get NCARMap data, NCARMapAS used for filtering and sorting the cards once get the page
axios
.get(
"http://localhost:9200/ncar_index/ncar/_search?size=100&sort=date:desc"
) //size to define the total docs to get / sort: sort the data for which field you want: asc or desc (desc for reverse)
.then((resp) => {
console.log(resp);
this.setState({
NCARMap: resp.data.hits.hits,
NCARMapAS: resp.data.hits.hits,
});
});
}
//function that handle the onChange on searchbar
handleChange(event) {
console.log(event.target.value);
this.setState({
search_query: event.target.value,
highlight: event.target.value,
});
axios
.get(
`http://localhost:9200/ncar_index/ncar/_search?q=${this.state.search_query}&size=100&sort=date:desc&analyzer=whitespace`
)
.then((resp) => {
if (event?.target?.value == "") {
// if the searchbar empty set default cards
this.setState({
NCARMap: this.state.NCARMapAS,
noPlaceFound: false,
});
} else {
if (resp.data.hits.hits.length > 0 && this.state.search_query != "") {
// go for new search when there is a result and searchbar not empty
this.setState({
NCARMap: resp.data.hits.hits,
noPlaceFound: false,
});
console.log("Successful");
} else {
// if there is no result make noplacefount true to print a message and show no card
if (resp.data.hits.hits.length == 0) {
this.setState({ noPlaceFound: true });
console.log("Length is equal 0");
}
}
}
});
}
DropDownChangeOne(event) {
console.log("lol");
this.setState({
search_query_drop: "approvetool:أمر",
});
console.log(this.state.search_query_drop);
axios
.get(
`http://localhost:9200/ncar_index/ncar/_search?q=${this.state.search_query_drop}&size=100&sort=date:desc`
)
.then((resp) => {
if (this.state.search_query_drop == "") {
// if the searchbar empty set default cards
this.setState({
NCARMap: this.state.NCARMapAS,
noPlaceFound: false,
});
} else {
if (
resp.data.hits.hits.length > 0 &&
this.state.search_query_drop != ""
) {
// go for new search when there is a result and searchbar not empty
this.setState({
NCARMap: resp.data.hits.hits,
noPlaceFound: false,
});
console.log("Successful");
} else {
// if there is no result make noplacefount true to print a message and show no card
if (resp.data.hits.hits.length == 0) {
this.setState({ noPlaceFound: true });
console.log("Length is equal 0");
}
}
}
});
}
render() {
return (
//HTML FILE Converted to React
<div>
<meta charSet="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta httpEquiv="X-UA-Compatible" content="ie=edge" />
<title>منشآت</title>
<link
rel="shortcut icon"
href="/images/favicon.png"
type="image/x-icon"
/>
{/*============= ScrollToTop Section Starts Here =============*/}
<div className="overlayer" id="overlayer">
<div className="loader">
<div className="loader-inner" />
</div>
</div>
<a href="#0" className="scrollToTop">
<i className="fas fa-angle-up" />
</a>
<div className="overlay" />
{/*============= ScrollToTop Section Ends Here =============*/}
{/*============= Header Section Starts Here =============*/}
<header className="header-section">
<div className="container">
<div className="header-wrapper">
<div className="logo-area">
<div className="logo">
<a href="/">
<img src="/images/logo/logo.png" alt="logo" />
</a>
</div>
<div className="support headFont">
الصفحة الرئيسية
</div>
</div>
<ul className="menu headFont">
<li>
{/*Here we need to change the herf link*/}
الوثائق و المحفوظات
</li>
<li>
الأخبار
</li>
<li>
{/*Here we need to change the herf link*/}
التغريدات
</li>
{/*Here we need to change the herf link*/}
{/* I want to know the difference between the two below */}
<li className="d-md-none text-center">
<a href="#0" className="m-0 header-button">
تسجيل دخول
</a>
</li>
</ul>
<div className="header-bar d-lg-none">
<span style={{ backgroundColor: "#00A7CF" }} />
<span style={{ backgroundColor: "#00A7CF" }} />
<span style={{ backgroundColor: "#00A7CF" }} />
</div>
{/* <div class="header-right"> */}
{/*Here we need to change the herf link*/}
{/* تسجيل دخول
</div> */}
</div>
</div>
</header>
{/*============= Header Section Ends Here =============*/}
{/*============= Banner Section Starts Here =============*/}
<section
className="banner-2 bg_img"
data-background="/images/banner/background3.png"
>
<div className="container">
<div className="banner-content-2">
<h1 className="title cl-white">
مرحباً بك في قسم الوثائق والمحفوظات
</h1>
<p className=" cl-white">
يحتوي هذا القسم على الوثائق والمحفوظات المعتمدة من المركز الوطني
للوثائق والمحفوظات
</p>
<form className="search-form round">
<input
type="text"
style={{ textAlign: "right", color: "black" }}
onChange={this.handleChange}
placeholder="... ابحث هنا"
/>
<button type="submit">
<i className="flaticon-search" />{" "}
<span className="d-none d-sm-inline-block">ابحث</span>
</button>
</form>
</div>
</div>
</section>
{/*============= Banner Section Ends Here =============*/}
{/*============= How Search Section Starts Here =============*/}
<div className="how-search-section padding-bottom mt--93">
<div className="container">
<div className="row mb-30-none justify-content-center">
<div className="filter-rtl">
{/*begin::Body*/}
<div className="card-body filters">
{/*begin::Form*/}
<form>
{/*begin::Categories*/}
<div className="form-group mb-11">
<label className="font-size-h3 font-weight-bolder text-dark mb-7">
التنصيفات
</label>
{/* start dropdown menue */}
<div className="dropdown">
<button
className="btn btn-secondary dropdown-toggle"
type="button"
id="dropdownMenuButton"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
أداة الاعتماد
</button>
<div
className="dropdown-menu"
aria-labelledby="dropdownMenuButton"
>
<a
className="dropdown-item"
onClick={this.DropDownChangeOne}
>
أمر ملكي
</a>
<a className="dropdown-item" href="#">
مرسوم ملكي
</a>
<a className="dropdown-item" href="#">
قرار مجلس الوزراء
</a>
<a className="dropdown-item" href="#">
أمر سامي
</a>
<a className="dropdown-item" href="#">
قرار وزاري
</a>
<a className="dropdown-item" href="#">
قرار مجالس وهيئات
</a>
<a className="dropdown-item" href="#">
قرار إداري
</a>
<a className="dropdown-item" href="#">
توجيه سامي
</a>
</div>
</div>
<div className="dropdown">
<button
className="btn btn-secondary dropdown-toggle"
type="button"
id="dropdownMenuButton"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
فئة الوثيقة
</button>
<div
className="dropdown-menu"
aria-labelledby="dropdownMenuButton"
>
<a className="dropdown-item" href="#">
الاتفاقيات و المعادات الدولية العامة
</a>
<a className="dropdown-item" href="#">
الاتفاقيات الدولية الثنائية
</a>
<a className="dropdown-item" href="#">
الاتفاقيات الدولية متعددة الأطراف
</a>
</div>
</div>
</div>
{/* end dropdown menue */}
{/* Start: : DateRangePickerComponent */}
<DateRangePickerComponent></DateRangePickerComponent>
{/* End: : DateRangePickerComponent */}
{/*end::Categories*/}
<button
type="submit"
className="btn btn-primary font-weight-bolder mr-2 px-8"
>
إعادة ضبط
</button>
<button
type="reset"
className="btn-submit btn btn-clear font-weight-bolder text-muted px-8"
>
بحث
</button>
</form>
{/*end::Form*/}
</div>
{/*end::Body*/}
</div>
<div className="general-card">
{this.state.noPlaceFound ? (
<h3 className="noPlaceFound">
<i className="fas fa-exclamation-circle fa-sm WarnIcon"></i>
لا يوجد نتائج
</h3>
) : (
this.state.NCARMap.map((v) => CreateCards(v._source))
)}
{console.log(this.state.NCARMap)}
</div>
</div>
</div>
</div>
{/*============= How Search Section Ends Here =============*/}
{/*============= Footer Section Starts Here =============*/}
<footer className="footer-section pt-70-145">
<div className="dot-slider bg_img" />
<div className="container">
<div className="row mb--50 justify-content-between">
<div className="col-sm-8 col-lg-4">
<div className="footer-widget widget-about"></div>
</div>
</div>
</div>
<div className="footer-bottom cl-white">
<p>جميع الحقوق محفوظة © 2021</p>
</div>
</footer>
{/*============= Footer Section Ends Here =============*/}
</div>
);
}
}

Case 1: Using map in this case:
{
["أمر ملكي", ...].map((text, i) => {
return (
<a key="i" href="" className="dropdown-item" onClick={() => this.DropDownChangeOne("approvetool:أمر")}> // Your query for each element
{text}
</a>
);
});
}
Case 2: Pass query to DropDownChangeOne
DropDownChangeOne(query) {
this.setState({
search_query_drop: query,
});
axios
.get(
`http://localhost:9200/ncar_index/ncar/_search?q=${query}&size=100&sort=date:desc`
)
.then((resp) => {
...
});
}

Firstly change the onclick function
<a className="dropdown-item" onClick={(e) => this.DropDownChangeOne(e, 'approvetool:أمر')} >
Then in function:
DropDownChangeOne(event, value) {
console.log("lol");
this.setState({
search_query_drop: value,
});
console.log(value);
axios
.get(
`http://localhost:9200/ncar_index/ncar/_search?q=${value}&size=100&sort=date:desc`
)
.then((resp) => {
....
....
....
})
}

Related

set a different color to each categories with javascript

I'm trying to achieve something in javascript
I want to set a specific color to each categories
For exemple :
if catergory.name == x then color = blue
if category.name == y then color = red
...
I tried like this, but I think I miss something :
categories.forEach(category => {
if (category.attributes.slug = "animation") {
cat.style.color = animColor;
}
if (category.attributes.slug = "decor") {
cat.style.color = decorColor;
}
if (category.attributes.slug = "illustrations") {
cat.style.color = illuColor;
}
if (category.attributes.slug = "developpement-visuel") {
cat.style.color = devVisuel;
}
if (category.attributes.slug = "realisations") {
cat.style.color = real;
}
if (category.attributes.slug = "croquis") {
cat.style.color = croquis;
}
});
<div>
<Header
categories={categories}
homepage={homepage} />
<div className="hidden md:block px-5 pt-10">
<a className="hover:no-underline " href="/">
<h3 className="text-xl uppercase tracking-widest mb-4">{homepage.attributes.hero.title}</h3>
</a>
<h5 className="text-sm mb-10">{homepage.attributes.bio.text}</h5>
<nav>
<ul>
{categories.map((category) => {
return (
<li key={category.id} className="mb-4">
<Link href={`/category/${category.attributes.slug}`}>
<a id="cat" className="uppercase font-light text-sm">{category.attributes.name}</a>
</Link>
</li>
)
})}
</ul>
</nav>
</div>
</div>
Can you help me find the solution?
You can use an object as a dictionary translating "slug" to "color".
You can set the color attribute in the categories.map inner function.
I removed id="cat" because that would result in duplicated IDs which are never good.
const colorMap = {
"animation": animColor,
"decor": decorColor,
"illustrations": illuColor,
"developpement-visuel": devVisuel,
"realisations": real,
"croquis": croquis
};
<div>
<Header
categories={categories}
homepage={homepage} />
<div className="hidden md:block px-5 pt-10">
<a className="hover:no-underline " href="/">
<h3 className="text-xl uppercase tracking-widest mb-4">{homepage.attributes.hero.title}</h3>
</a>
<h5 className="text-sm mb-10">{homepage.attributes.bio.text}</h5>
<nav>
<ul>
{categories.map((category) => {
return (
<li key={category.id} className="mb-4">
<Link href={`/category/${category.attributes.slug}`}>
<a className="uppercase font-light text-sm" style=`color: ${colorMap[category.attributes.slug]}`>{category.attributes.name}</a>
</Link>
</li>
)
})}
</ul>
</nav>
</div>
</div>

Calling data from the API for child component in Next.js

I am working on a header component. Here is the code:
import style from '../../styles/header.css';
import '../../styles/globals.css';
export default function Header({data}){
const [showMe, setShowMe] = useState(false);
function toggle(){
console.log("toggle")
setShowMe(!showMe);
}
return(
<>
<div className="header">
<div className="web-header">
<div className="first-header">
<div className="info-strip">
<ul>
<li>
Contact Us
</li>
<li>
7 Day Returns
</li>
<li>
Track Order
</li>
<li>
Return Order
</li>
<li>
Survey
</li>
</ul>
</div>
<div className="right-block d-flex">
<div className="login">
<span className="image"></span>
<span className="text">Log In
<div className="account-box">
</div>
</span>
</div>
<div className="cart">
<span className="cart-image">
</span>
<span className="text">Cart</span>
</div>
</div>
</div>
<div className="second-header">
<div className="header-logo">
<img src="https://www.mirraw.com/assets/logo-red.png" />
</div>
<div className="search">
<input placeholder="Search Something.." />
<button></button>
</div>
</div>
<div className="third-header">
<div className="container-fluid">
<ul className="menu">
{data.menus.map((post, index) => {
return (
<li className="menu-list">
{post.title}
<div className="megabox">
<ul className="wrapper">
{post.menu_columns.map((subItems, sIndex) => {
return <li>
<span className="menu-link">
{subItems.title}
</span>
<ul className="category">
{subItems.menu_items.map((x) => {
return <li>
{x.title}
</li>
})}
</ul>
</li>;
})}
</ul>
</div>
</li>)})}
</ul>
</div>
</div>
</div>
<div className="mobile-screen">
<div className="mobile-header">
<div className="mobile-menu">
<div className="menu-icon">
<div className="wrapper">
<input type="checkbox" id="navigation" />
<label for="navigation">
+
</label>
<div className="right-card">
<img src="https://www.mirraw.com/assets/logo-red.png" />
<p className="app-install">
<span>Download app</span>
</p>
<div className="cart">
<span className="cart-image"></span>
{/* <span className="text">Cart</span> */}
</div>
</div>
<nav>
<ul>
<li className="menu-heading">
<span>Menu</span>
<span>
<label for="navigation">X</label>
</span>
</li>
{data.menus.map((post, index) => {
return (
<li className="menu-list">
{post.title} <span onClick={toggle}>+</span>
<ul style={{display: showMe?"block":"none"}} className="category-one">
{post.menu_columns.map((subItems, sIndex) => {
return <li>
{subItems.title}
<span>+</span>
<ul className="category-two">
{subItems.menu_items.map((x) => {
return <li>
{x.title}
</li>
})}
</ul>
</li>;
})}
</ul>
</li>)})}
</ul>
</nav>
</div>
</div>
</div>
<div className="scroll-menu-list">
<ul className="mb-0">
{data.menus.map((post, index) => {
return (
<li className="menu-list">{post.title}</li>
)})}
</ul>
</div>
</div>
</div>
</div>
</>
)
}
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`https://api.mirraw.com/api/v1/menu`);
const data = await res.json();
// Pass data to the page via props
return { props: { data } }
}
Code is working fine if I render this page only, but when I import this component in other component, it threw error:
Server Error
TypeError: Cannot read property 'menus' of undefined
This error happened while generating the page. Any console logs will be displayed in the terminal window.
What could be the approach of getting value from the API for child component?
getServerSideProps can only be used within page components, which is why it works when you render this component as a page.
If you want to this to be a reusable component that can be called from other components and/or pages you'll need to pass the data you get at the page level (from getServerSideProps, for instance) down to it.
// pages/index.js
import Header from "../components/header"
export default function IndexPage({ data }) {
return (
<Header data={data} />
)
}
export async function getServerSideProps() {
const res = await fetch(`https://api.mirraw.com/api/v1/menu`);
const data = await res.json();
return { props: { data } }
}

Mapping nested array inside mapped array in React JSX

I'm trying to write a dashboard sidebar which has a couple of "primary" buttons which (via Bootstrap) collapse a number of "secondary" buttons. I want to be able to easily update and style the whole thing so writing static markup is out of the picture. Here is one object out of the array:
const menuArray = [
{
primaryText: "Applications",
primaryIcon: "fa fa-rocket",
primaryURL: "/applications",
secondaries: [
{
secondaryText: "Softwares",
secondaryURL: "/softwares",
},
{
secondaryText: "Videogames",
secondaryURL: "/videogames",
},
{
secondaryText: "Tools",
secondaryURL: "/tools",
},
],
},
]
And here is the function rendering the array which i'm simply calling in the JSX markup by {renderMenuArray}
const renderMenuArray = menuArray.map((menuItem) => (
<li className="py-2">
<button
data-target={`#${menuItem.primaryText}Submenu`}
data-toggle="collapse"
aria-expanded="false"
className="btn btn-dark btn-menu btn-block pl-0 mb-1"
>
<Link to={menuItem.primaryURL}>
<span className="mr-3">
<i className={menuItem.primaryIcon}></i>
</span>
{menuItem.primaryText}
</Link>
</button>
<div
className="card-body collapse ml-5"
id={`${socialItem.primaryText}Submenu`}
>
<ul className="list-unstyled">
<li>
<Link className="small" to="/applications/softwares">
<span className="mr-3">
<i className="fa fa-chevron-right"></i>
</span>
Softwares
</Link>
</li>
</ul>
</div>
));
I can render the "primary" objects with no problem at all, but I want each "primary" object ( each iteration of the parent array) to each iterate through the count of "secondaries" array ( which is going to be different for each "primary" object).
I'm a beginner developer.
The object passed into the callback function for the map, menuItem has the included property secondaries. You can use map on this property since secondaries is an array, simply place the map inside of your JSX.
<div
className="card-body collapse ml-5"
id={`${socialItem.primaryText}Submenu`}
>
<ul className="list-unstyled">
{menuItem.secondaries.map((subItem) => {
...
})
</ul>
</div>
P.S. you forgot to close your last div tag, and you have a second </li> instead of a </ul>
This'll work (made it a bit more functional, to give you an example of what's possible with functional React components)
const menuArray = [
{
primaryText: "Applications",
primaryIcon: "fa fa-rocket",
primaryURL: "/applications",
secondaries: [
{
secondaryText: "Softwares",
secondaryURL: "/softwares"
},
{
secondaryText: "Videogames",
secondaryURL: "/videogames"
},
{
secondaryText: "Tools",
secondaryURL: "/tools"
}
]
}
];
export default function App(props) {
function renderSecondaryMenu(items) {
return items.map(secondaryItem => {
return (
<li>
<Link className="small" to={secondaryItem.secondaryURL}>
<span className="mr-3">
<i className="fa fa-chevron-right" />
</span>
{secondaryItem.secondaryText}
</Link>
</li>
);
});
}
function renderMenuArray() {
return menuArray.map(menuItem => {
return (
<li className="py-2">
<button
data-target={`#${menuItem.primaryText}Submenu`}
data-toggle="collapse"
aria-expanded="false"
className="btn btn-dark btn-menu btn-block pl-0 mb-1"
>
<Link to={menuItem.primaryURL}>
<span className="mr-3">
<i className={menuItem.primaryIcon} />
</span>
{menuItem.primaryText}
</Link>
</button>
<div
className="card-body collapse ml-5"
id={`${menuItem.primaryText}Submenu`}
>
<ul className="list-unstyled">
{renderSecondaryMenu(menuItem.secondaries)}
</ul>
</div>
</li>
);
});
}
return <div className="App">{renderMenuArray()}</div>;
}
I don't think you gain a lot from defining the sidebar as an object, unless you are using the same Sidebar component with different sets of buttons and you wanna be able to switch between them. JSX is already a markup language, so it's declarative.
You could define simply the Sidebar as
const Sidebar = () => (
<PrimaryItem text="Applications" icon="fa fa-rocket" url="/applications">
<SecondaryItem text="Softwares" url="/softwares" />
<SecondaryItem text="Videogames" url="/videogames" />
<SecondaryItem text="Tools" url="/tools" />
</PrimaryItem>
)
And then implement each component as you need to display them. I think this is cleaner and easier to maintain and modify.

Maximum depth exceeded when trying to redirect from child state to parent state

I am trying to pass data from child to parent state using
I have to state ProjectList and Header, the header(website header) state is the child compenent of parent, there links on header,if it clicks the link then I am getting an id through that link and then passing that id to through redirect.
but it gives me error maximum dept exceeded.The id I want to passs from header to project list is also coming from other state which is not the child of project list.
ProjectList State:
class ProjectList extends React.Component{
constructor(props){
super(props);
this.showDetail=this.showDetail.bind(this);
this.state={
category_projects:[],
projectPage:false,
clk_project:null,
category:[]
}
}
componentDidMount() {
fetch(`http://127.0.0.1:8000/portfolio/get_category_project/`+this.props.match.params.id+'/').then(response => response.json())
.then(projectsJson => this.setState({category_projects: projectsJson},()=>{
this.sortProjects()
}))
fetch('http://127.0.0.1:8000/portfolio/create_category/')
.then(response=>response.json())
.then(categoryJson => this.setState({category: categoryJson},()=>{
this.sortCategory()
}))
}
sortCategory = ()=>{
let sortArray=this.state.category;
let swap;
for (let i=0;i<sortArray.length;i++)
{
for (let j=0;j<sortArray.length;j++){
if(sortArray[i].category_rank>sortArray[j].category_rank){
swap=sortArray[i];
sortArray[i]= sortArray[j];
sortArray[j]=swap;
}
}
}
this.setState({category:sortArray})
};
showDetail=(evt)=>{
evt.preventDefault();
this.setState({projectPage:true});
this.setState({clk_project:JSON.parse(evt.currentTarget.getAttribute('data-item'))});
};
sortProjects=()=>{
let sortArray=this.state.category_projects;
let swap;
for (let i=0;i<sortArray.length;i++)
{
for (let j=0;j<sortArray.length;j++){
if(sortArray[i].project_rank>sortArray[j].project_rank){
swap=sortArray[i];
sortArray[i]= sortArray[j];
sortArray[j]=swap;
}
}
}
this.setState({category_projects:sortArray})
};
render() {
let redirect=null;
if (this.state.projectPage){
redirect=<Redirect to={`/project/${this.state.clk_project.id}`}/>
}
return(
<div>
{redirect}
<div className="site_wrapper">
<div className="clearfix">
</div>
<Header category={this.state.category}/>
<div className="clearfix">
</div>
<div className="page_title2">
<div className="container">
<div className="title"><h2>Projects</h2></div>
</div>
</div>
<div className="clearfix">
</div>
<div className="container">
<br />
{this.state.category_projects.map(proj=>{
return(
<div className="column">
<img data-item={JSON.stringify(proj)} onClick={this.showDetail} src={"http://127.0.0.1:8000"+proj.file} alt="Snow" className="ImgWidth"/>
</div>
)
})}
</div>
<div className="clearfix margin_top5">
</div>
<div className="footer_graph">
</div>
<Footer projects={this.state.category_projects} id={this.props.match.params.id}/>
</div>
</div>
)
}
}
Header State:
class Header extends React.Component{
constructor(props){
super(props);
this.showCatDetail=this.showCatDetail.bind(this);
this.state={
category:[],
clk_category:[],
detail:false
}
}
showCatDetail=(e)=>{
e.preventDefault();
this.setState({detail:true,clk_category:JSON.parse(e.currentTarget.getAttribute('data-item'))},()=>{
console.log(this.state.clk_category)
});
};
render(){
let hreflink=null;
let redirect=null;
if (this.state.detail){
redirect=<Redirect to={`/category_project/${this.state.clk_category.id}`}/>
}
return(
<div>
{redirect}
<header id="header">
<div id="trueHeader">
<div className="wrapper">
<div className="container">
<div className="logo">
<a href={hreflink} id="logo">
</a>
</div>
<div className="menu_main">
<div className="navbar yamm navbar-default">
<div className="container">
<div className="navbar-header">
<div className="visibledevice">
<ul className="nav navbar-nav">
<li><a href={hreflink} className="active">
<i className="fa fa-home">
</i> Home</a></li>
</ul>
</div>
</div>
<div className="navbar-collapse collapse pull-right">
<ul className="nav navbar-nav">
<li><a href={hreflink} className="active">
<i className="fa fa-home">
</i> Contact Us</a></li>
{this.props.category.map(cat=>{
return(
<li data-item={JSON.stringify(cat)} onClick={(e)=>this.showCatDetail(e)}><a href={hreflink} >
<i className="fa fa-home">
</i>{cat.category_name}</a></li>
)
})}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
</div>
)
}
}
this.props.match.params.id this id I want to get from header as I trying to pass from in header.The this.props.match.params.id in project list can come from Header or other state.Please need suggestion how to pass this id from header to project list as well as the id can comes from other state to project.

Build dropdown menu with array passed from parent component [duplicate]

This question already has answers here:
map function not working in React
(3 answers)
Index inside map() function
(4 answers)
Closed 25 days ago.
I am trying to build a dropdown-menu and add data from my array to the dropdown-item. My current code isn't returning anything into my const Users. How can I use the array to add data into the dropdown-item?
UserDisplay component
const UserDisplay = ({ users }) => {
const Users = users.map(user => {
let i = 0;
<a className="dropdown-item" href="#">
{user[i]}
</a>;
i++;
});
return (
<div className="dropdown-menu" id="users">
<a className="dropdown-item" href="#">
Online Users
</a>
<div className="dropdown-divider" />
{Users}
</div>
);
};
Parent Component ChatLayout
return (
<div className="chat navbar fixed-bottom">
<div className="btn-group dropup">
<button
type="button"
className="btn btn-secondary dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
Chat
</button>
<UserDisplay users={[this.state.users]} />
</div>
<ul id="messages">
<div />
</ul>
<form onSubmit={this.onSubmit}>
<textarea
name="message"
placeholder="Enter your message here"
autoComplete="off"
type="submit"
onKeyDown={this.onEnterPress}
value={this.state.message}
onChange={this.onChange}
/>
<input type="submit" className="btn btn-info btn-block mt-4" />
</form>
</div>
);
You don't need to define and iterate i.. the .map already keeps track of the array index. Assuming users has data it should work like this...
UserDisplay(users) {
const Users = users.map((user,i) => {
return (
<a className="dropdown-item" key={i} href="#">
{user}
</a>)
});
return (
<div className="dropdown-menu" id="users">
<a className="dropdown-item" href="#">
Online Users
</a>
<div className="dropdown-divider" />
{Users}
</div>
);
};
Working Codeply: https://www.codeply.com/go/DnqpGhozra
You are destructing props object and get users out of it so its fine.
basically map returns a list of array so you dont have return anything.
You need to iterate to the first element of users like
const Users = users[0].map((user,i) => {
console.log(user);
return (
<a className="dropdown-item" key={i} href="#">
{user}
</a>)
});
OR just pass users directly
<UserDisplay users={this.state.users} />

Categories

Resources