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

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} />

Related

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

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) => {
....
....
....
})
}

document.querySelector is not working in my react component

function Slider() {
const track=document.querySelector('.slide__track')//To access the div with class slide track
console.log(track);
return (
<div className="slider">
<i className="fas fa-chevron-left"></i>
<div className="head">
<h1 className="title">Based on your last search</h1>
<h6>View more</h6>
</div>
<div className="slider_container">
<ul className="slider__track">
<li className="slider__items">
<Card />
</li>
</ul>
</div>
<i className="fas fa-chevron-right"></i>
</div>
);
}
i cannot access the div with class slide__track.
What is the problem here?
Or how can i access that element?
Try and use this code in useEffect()
useEffect(() => {
const track = document.querySelector('.slide__track')
// have access to it
}, []);
I think it's because it is running before the DOM has been rendered. Move the track code into useEffect.
import {useEffect} from "react";
function Slider() {
useEffect(() => {
const track=document.querySelector('.slide__track')//To access the div with class slide track
console.log(track);
});
return (
<div className="slider">
<i className="fas fa-chevron-left"></i>
<div className="head">
<h1 className="title">Based on your last search</h1>
<h6>View more</h6>
</div>
<div className="slider_container">
<ul className="slider__track">
<li className="slider__items">
<Card />
</li>
</ul>
</div>
<i className="fas fa-chevron-right"></i>
</div>
);
}
You should be probably be using ref's to access dom elements inside react. see docs: https://reactjs.org/docs/refs-and-the-dom.html - reason being, if you have the below in a loop, or have multiple instances on the page, you'll need to be more careful with the selector approach.
import React, { useRef, useEffect } from 'react';
function Slider() {
const slideTrackRef = useRef(null);
useEffect(() => {
if (slideTrackRef && slideTrackRef.current) {
console.log(slideTrackRef.current);
}
}, [slideTrackRef]);
return (
<div className="slider">
<i className="fas fa-chevron-left" />
<div className="head">
<h1 className="title">Based on your last search</h1>
<h6>View more</h6>
</div>
<div className="slider_container">
<ul className="slider__track" ref={slideTrackRef}>
<li className="slider__items">
<p>tst</p>
</li>
</ul>
</div>
<i className="fas fa-chevron-right" />
</div>
);
}
export default Slider;

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.

Issues passing data up React tree to change DOM

** This may be a simple answer, I'm new to React, thank you for any help ! **
Back story
I have a modal(bootstrap4) hidden inside the main app with a form inside that, when it rendered, the form is filled out based on the information from the selected recipe (more on that later.)
The recipes are stored locally and with this.state.currentRecipe I know which recipe is being selected (it is used as the index and is set to 0 by default.)
So, using this.state.currentRecipe as the index the first render naturally puts in the first recipe's information.
I attempted to solve this by making a function and passing it down the child components. The recipe-card has all the information and the edit button inside of it. So when the recipe-cards are all rendered by .map() I pass in their index and the function that was passed down in order to change the state of this.state.currentRecipe and re-render the DOM with the form having the new information.
What's wrong
Everything loads however, when I click the edit button the modal pops up with the first recipe always. It will even change this.state.currentRecipe but the DOM doesn't re-render with the proper recipe's information.
How do I get the form's information to update based on which recipe-card I'm in when I click the 'Edit' button?(there is a button in each card).
(and even if it did, would it just hide the modal again?)
Here is the link to the component folder of the repo https://github.com/JeremyWeisener/React-Recipe-box/tree/master/src/components
in case the code below isn't enough information
Here is the inside of the 4 main files I believe matter (cleaned up a bit and put here to make life easier)
app.js
import React, { Component } from 'react';
import RecipeCard from './recipe-card';
import RecipeBook from './recipe-book';
import AddRecipe from './add-recipe';
import RecipeEditer from './edit-recipe';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
currentRecipe: 0,
recipes: JSON.parse(localStorage.getItem('cookBook')),
updateKey: 0,
counter: 0
}
}
changeRecipe = (arg) => {
this.setState({currentRecipe:arg});
}
render() {
return (
<div>
<div>
<RecipeBook changeRecipe={this.changeRecipe.bind(this)} recipes={this.state.recipes} />
</div>
<div id="popUps">
<AddRecipe />
<RecipeEditer index={this.state.currentRecipe} forglory={this.state} />
</div>
<div id="editPopup">
</div>
</div>
);
}
}
recipe-book.js
import React from 'react';
import RecipeCard from './recipe-card';
const RecipeBook = (props) => {
var changeRecipe = props.changeRecipe;
console.log(props);
const DisplayRecipes = props.recipes.map((recipe, index) => {
return <RecipeCard index={index} key={index+1} recipe={recipe} changeRecipe={changeRecipe.bind(this)} />
})
return (
<div id="accordion" role="tablist" aria-multiselectable="true">
{DisplayRecipes}
<div>
<button className="btn btn-primary" type="button" data-toggle="modal" data-target="#addRecipe"> Add Recipe </button>
</div>
</div>
);
}
export default RecipeBook;
recipe-card.js
import React from 'react';
import Ingredients from './recipe-ingredients';
import Steps from './recipe-steps';
import RecipeEditer from './edit-recipe';
const RecipeCard = (props) => {
const changeRecipe = props.changeRecipe;
return (
<div>
{/*Card Start*/}
<div className="recipe card">
{/*Header*/}
<div className="card-header" role="tab" id={`heading${props.index}`}>
<h5 className="mb-0">
<a data-toggle="collapse" data-parent="#accordion" href={`#collapse${props.index}`} aria-expanded="true" aria-controls={`collapse${props.index}`}>
{props.recipe.title}
</a>
</h5>
</div>
{/*End Header*/}
{/*Collapse Div*/}
<div id={`collapse${props.index}`} className="collapse" role="tabpanel" aria-labelledby={`heading${props.index}`}>
{/*Card IMG*/}
<img className="card-img-top" src="./img/Fried Chik'n-edit1.jpg" />
{/*Card Block*/}
<div className="card-block">
<p className="card-text">
</p>
{/* Ingredients */}
<h3>Ingredients</h3>
<Ingredients parts={props.recipe.ingredients} />
{/* Steps */}
<h3>Steps</h3>
<Steps levels={props.recipe.steps} />
Print Recipe
{/*Edit Button is here*/}
<button onClick={() => {changeRecipe(props.index)}} className="btn btn-success" type="button" data-toggle="modal" data-target="#editRecipe"> Edit Recipe </button>
{/*Edit Button is here*/}
Delete Recipe
</div>
{/*End Card Block*/}
</div>
{/*End Collapsable*/}
</div>
{/*End Card*/}
</div>
);
}
export default RecipeCard;
edit-recipe.js
import React from 'react';
const RecipeEditer = (props) => {
var index = props.index;
var cookBook = JSON.parse(localStorage.getItem("cookBook"));
var editMe = cookBook[props.forglory.currentRecipe];
const UpdateRecipe = () => {
var formData = $('#recipeEditer').serializeArray();
var newRecipe = {};
newRecipe.title = formData[0]['value'];
newRecipe.image = formData[1]['value'];
newRecipe.ingredients = formData[2]['value'].split(',');
newRecipe.steps = formData[3]['value'].split(',');
cookBook[index] = newRecipe;
localStorage.setItem("cookBook", JSON.stringify(cookBook));
}
return (
<div className="modal fade" id="editRecipe" tabIndex="-1" role="dialog" aria-labelledby="editRecipeLabel" aria-hidden="false">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
{/* Title */}
<h5 className="modal-title" id="exampleModalLabel">
Edit Recipe
</h5>
<button type="button" className="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="false">×</span>
</button>
</div>
<div className="modal-body">
<form id="recipeEditer" name="editRecipe">
<label htmlFor="name"><h4>Name</h4></label>
<input id="name" className="form-control" name="title" type="text" defaultValue={editMe.title} />
<label htmlFor="image"><h4>Image</h4></label>
<input id="image" className="form-control" name="image" type="text" defaultValue={editMe.image} />
<label htmlFor="ingredients"><h4>Ingredients</h4></label>
<textarea id="ingredients" className="form-control" name="ingredients" rows="4" cols="48" defaultValue={editMe.ingredients}></textarea>
<label htmlFor="steps"><h4>Steps</h4></label><br/>
<textarea id="steps" className="form-control" name="steps" cols="48" rows="4" defaultValue={editMe.steps} ></textarea>
</form>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data-dismiss="modal">Close</button>
{/*Submit Button*/}
<button onClick={UpdateRecipe} type="button" className="btn btn-success" data-dismiss="modal">Change Recipe</button>
{/*Submit Button*/}
</div>
</div>
</div>
</div>
);
}
export default RecipeEditer;
thank you very much if you even glanced, if there is any more information that can help please don't hesitate to ask !
You are binding changeRecipe to this in recipe-book.js, thus setting its context to RecipeBook.
Try changing
<RecipeCard index={index} key={index+1} recipe={recipe} changeRecipe={changeRecipe.bind(this)} />
to
<RecipeCard index={index} key={index+1} recipe={recipe} changeRecipe={changeRecipe} />
You may not even have to use bind in app.js, since changeRecipe is defined as an arrow function.

When selecting item from an array renders all items react js

I have the following problem, when selecting an item through a checkbox and pressing a button so that that selected item is added to my new array, all the items are added.
I use the function map and return the component with their respective key and item:
renderFiltersInlcuye() {
if(this.props.incluye){
return this.props.incluye.map((item, index) =>{
return <BusquedaPaquetesFiltrosAplicadosItems
key = {item.value}
item= {item}
onClickClose={this.removeItemIncluye.bind(this,index)}
/>
})
}
}
And in my other component I render the following:
render () {
return(
<ul>
<li>
<span className="badge badge-info " >
<button onClick={this.props.onClickClose} type="button" className="close" ><i className="fas fa-times-circle"></i> </button>
{this.props.item.texto}
</span>
</li>
</ul>
);
}

Categories

Resources