React change variable onChange-method - reactjs

I am experimenting with React and I have the following problem. Different employees are listed in the "medewerker:" dropdown. When 1 is selected, the data is replaced by the value of the selection using the 'handelChangeEmployee' function in the 'employeeOrder' variable. In the console.log everything changes as expected. Only if I read variable: 'employeeOrder' will it continue to show the previously set value. and this is not being replaced, is this possible? and if so how?
So what I want to achieve is that when a selection is made, the value in the existing variable is replaced with the value of the selection.
The code that I am currently using is:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import styles from "assets/jss/material-dashboard-react/views/dashboardStyle.js";
import { Container } from "react-bootstrap";
import { Row } from "react-bootstrap";
import { Col } from "react-bootstrap";
import Close from '#material-ui/icons/Close';
import { render } from "react-dom";
const useStyles = makeStyles(styles);
export default function ChaskDesk() {
const employee = ["Robin","Raoul","Joppe "];
const service = ["Knippen","Scheren","Wassen"];
const counting = [1,2,3,4,5,6];
const gender = ["man", "vrouw", "kind"];
const client = ["Passant"];
let employeeOrder = 'Raoul';
const serviceOrder = [];
const countingOrder = [];
const genderOrder = [];
const clientOrder = "";
const payment = 0;
const classes = useStyles();
const handelChangeGender = function(event){
genderOrder.push(event.target.value);
console.log(genderOrder);
};
const handelChangeService = function(event){
serviceOrder.push(event.target.value);
console.log(serviceOrder);
};
let handelChangeEmployee = function(event){
console.log(employeeOrder);
employeeOrder = event.target.value;
console.log(employeeOrder);
};
return (
<div>
<Container className={classes.containerPixelActive}>
<h3>Afrekenen</h3>
<Row className={classes.tablePixelRow}>
<Col md={8} className={classes.rowChashdesk}>
<form>
<Row>
<Col md={6}>
<label>
Klant:
</label>
<br/>
<select >
{
client.map(function(item, i){
return <option key={i} value={item}>{item}</option>
})
}
</select>
</Col>
</Row>
<Row>
<Col md={6}>
<div className={classes.rowOfForm}>
<label>
Gender:
</label>
<br/>
<select onChange={handelChangeGender}>
{
gender.map(function(item, i){
return <option key={i} value={item}>{item}</option>
})
}
</select>
</div>
</Col>
</Row>
<Row>
<Col md={6}>
<div className={classes.rowOfForm}>
<label>
Behandeling:
</label>
<br/>
<select onChange={handelChangeService}>
{
service.map(function(item, i){
return <option key={i} value={item}>{item}</option>
})
}
</select>
</div>
</Col>
<Col md={6}>
<div className={classes.rowOfForm}>
<label>
Medewerker:
</label>
<br/>
<select onChange={handelChangeEmployee}>
{
employee.map(function(item, i){
return <option key={i} value={item}>{item}</option>
})
}
</select>
</div>
</Col>
</Row>
<Row>
<Col md={6}>
<div className={classes.rowOfForm}>
<label>
Verkregen behandeling:
</label>
<br/>
<input type="text" name="name" />
</div>
</Col>
<Col md={2}>
<div className={classes.rowOfForm}>
<label>
Aantal:
</label>
<br/>
<select>
{
counting.map(function(item, i){
return <option key={i} value={item}>{item}</option>
})
}
</select>
</div>
</Col>
<Col md={2}>
<div className={classes.rowOfForm}>
<label>
Prijs:
</label>
<br/>
<input type="text" name="name"/>
</div>
</Col>
<Col md={2}>
<div className={classes.rowIcon}>
<Close size={20} ></Close>
</div>
</Col>
</Row>
</form>
</Col>
<Col md={3} className={classes.rowChashdesk}>
<h5>Totaal overzicht</h5>
<h6>Medewerker</h6>
<p>{employeeOrder}</p>
<h6>Behandeling</h6>
<p>{serviceOrder}</p>
<h6>Aantal</h6>
<p>{countingOrder}</p>
<h6>Klant</h6>
<p>{clientOrder}</p>
<h6>Te betalen</h6>
<p>{payment}</p>
</Col>
</Row>
</Container>
</div>
);
}

The only way a react component knows to rerender is by your component (or some component above it) settings state. You're not using state, so it doesn't rerender.
Change this:
let employeeOrder = 'Raoul';
To this:
import { useState } from 'react';
// ... code omitted
const [employeeOrder, setEmployeeOrder] = useState('Raoul')
And change your handler to:
const handelChangeEmployee = function(event) {
setEmployeeOrder(event.target.value)
}
You will need to do similar things for genderOrder and ServiceOrder. You can't just push into an array and expect the page to update, you need to set state to a new array to cause the component to rerender. Don't mutate the old array, create a new one, as in:
setGenderOrder([...genderOrder, event.target.value])
For more info on useState and other hooks, see this page

Related

React.JS Object passing during onclick event

I am new to react,
I am using card, when card "on click" i need to get the card object and place it in form dynamically,
(full code)
My code:
// reactstrap components
import {useState} from "react"
import {
Card,
CardHeader,
CardBody,
CardTitle,
Col,
Input,
FormGroup,
Form,
Container,
Row,
UncontrolledDropdown,
DropdownToggle,
DropdownItem,
DropdownMenu,
Button,
} from "reactstrap";
import Header from "components/Headers/Header.js";
import 'react-toastify/dist/ReactToastify.css';
import Navbar from "components/Navbars/modulenavbar"
import axios from "axios";
import React from "react";
import { Link } from "react-router-dom";
var apitoken= localStorage.getItem('apitoken');
const api=axios.create({baseURL:"https://api/v1/account"})
const options = {
headers: {'Authorization': apitoken}
}
const Accounts = () => {
const [accounts, setaccount] = React.useState([]);
const [loading, setLoading] = React.useState(true);
const [disabled, setDisabled] = useState(false);
React.useEffect(async () => {
const response = await api.get("/",options);
setaccount(response.data.response);
setLoading(false);
}, []);
if (loading) {
return <>Loading...</>;
}
function handleGameClick() {
setDisabled(!disabled);
}
This is were i get all my api value and append it
return (
<>
{accounts.map((student, index) => {
const { id, name, phone, email } = student //destructuring
return (
<>
<div style={{ width: "18rem" }} onClick={() => console.log(student)}>
I want to pass the object "Student" and use it in the default value of the forms shown below
<Card className="card-stats mb-4 mb-lg-1">
<CardBody>
<Row>
<div className="col">
<CardTitle className="h4 font-weight-bold mb-0">
{name}
</CardTitle>
<span className="h5">{phone}</span>
</div>
<div className="col">
<span className="h5">{email}</span>
</div>
</Row>
</CardBody>
</Card>
</div>
</>
)
})}
</>
)
}
Form Shows here
const Display = () => {
return (
<>
<Header />
<Container className="mt--7" fluid>
{/* Table */}
<Row>
<Col className="order-xl-1 " xl="2">
<CardHeader className="bg-white border-0">
<Row className="align-items-center">
<Col xs="8">
<Link to="/admin//accounts" className="ni ni-bold-left">
<span> View Account</span></Link>
</Col>
</Row>
</CardHeader>
<Card className="bg-secondary shadow navbar-nav-scroll">
<Accounts/>
</Card>
</Col>
<Col className="order-xl-1" xl="10">
<Card className="bg-secondary shadow">
<Navbar/>
<Row >
<Col className="shadow navbar-nav-scroll">
<Form>
<h6 className="heading-small text-muted mb-4">
Account Information
</h6>
<div className="pl-lg-4">
<Row>
<Col >
<FormGroup>
<label
className="form-control-label"
htmlFor="input-username"
>
Account Name
</label>
<Input
className="form-control-alternative"
id="input-username"
placeholder="Username"
type="text"
defaultValue={student.value}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col >
<FormGroup>
<label
className="form-control-label"
htmlFor="input-email"
>
Email address
</label>
<Input
className="form-control-alternative"
id="input-email"
placeholder="jesse#example.com"
type="email"
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col >
<FormGroup>
<label
className="form-control-label"
htmlFor="input-email"
>
Phone
</label>
<Input
className="form-control-alternative"
id="input-phone"
placeholder="Phone"
type="text"
/>
</FormGroup>
</Col>
</Row>
</div>
</Form>
</Col>
<Col xs="9">
<Card className="card-stats mb-4 mb-lg-0">
<CardBody>
<div>
<Row className="align-items-center">
<Col xs="8">
</Col>
<Col className="text-right" xs="4">
<Button
color="success"
href="#pablo"
// onClick={save}
>
Save
</Button>
</Col>
</Row>
</div>
</CardBody>
</Card>
</Col>
</Row>
</Card>
</Col>
</Row>
</Container>
</>
);
};
export default Display;
Note:The above three sections of code is in the single component
I just want to dynamically append the values from object during "on click" event
Thanks in advance
You can store the clicked student value in state and pass it on to whichever component needs it as props
const Accounts = () => {
const [selectedStudent, setSelectedStudent] = useState({});
...
const handleStudentClick = (student) => {
setSelectedStudent(student)
}
return (
<>
{accounts.map((student, index) => {
const { id, name, phone, email } = student //destructuring
return (
<>
<div style={{ width: "18rem" }} onClick={() => handleStudentClick(student)}>
Now you can pass selected student as props to your child component

Child component renders even though its being memoized

Child component renders even though props are not altered of it.
Following is the parent component
import Child from "./Child";
function Parent({
selected,
show,
setShow,
}) {
const [isRunNow, setIsRunNow] = useState(true);
const [isNotifyMe, setIsNotifyMe] = useState(false);
const handleNotify = useCallback(() => {
setIsNotifyMe(!isNotifyMe);
}, [isNotifyMe]);
const handleSchedule = useCallback(() => {
setIsRunNow(!isRunNow);
}, [isRunNow]);
const WindowForm = () => {
return (
<div>
<Row>
<Col span={12}>
<label className={styles.labelWeight}> Name : </label>
<input
type="text"
value={selected.name}
readOnly={true}
className={styles.input}
/>
<br></br>
<br></br>
<label className={styles.labelWeight}>Description : </label>
<input
type="text"
value={selected.description}
readOnly={true}
className={styles.input}
></input>
<br></br>
<br></br>
<input
type="checkbox"
name="runImm"
id="runImm"
checked={isRunNow}
onChange={handleSchedule}
></input>
<label> Schedule as soon as possible</label>
</Col>
<Col span={12}>
<input
type="checkbox"
name="notifyProcess"
id="notifyProcess"
checked={isNotifyMe}
onChange={handleNotify}
></input>
<label> Notify me when this process ends</label>
<br></br>
<br></br>
<label>Submission Notes : </label>
<textarea
name="notes"
id="notes"
rows="4"
cols="50"
disabled={!isNotifyMe}
></textarea>
</Col>
</Row>
<Row>
<Col span={24}>
<Child isRunNow={isRunNow} />
</Col>
</Row>
</div>
);
};
return (
<Modal
visible={show}
width={800}
centered
maskClosable={false}
onCancel={() => setShow(false)}
title="JKM"
>
<WindowForm />
</Modal>
);
}
Child component is as follows:
import Uploader from "./Uploader";
import Downloader from "./Downloader";
const { TabPane } = Tabs;
const areEqual = (prevProps, nextProps) => {
console.log("passed here"); // THIS IS NEVER LOGGED!!
return true;
};
function Child({ isRunNow }) {
console.log(
`Rendering Childe component...isRunNow value : ${isRunNow}`
);
return (
<div>
<Tabs defaultActiveKey="ka">
<TabPane tab="ka" key="ka">
Panel
</TabPane>
<TabPane tab="sa" key="sa" disabled={isRunNow}>
<Downloader />
</TabPane>
<TabPane tab="da" key="da">
<Uploader />
</TabPane>
</Tabs>
</div>
);
}
export default React.memo(Child, areEqual);
When I check or uncheck check box Notify me, the child component Child re-renders every time. It seems props are not equal and hence its re-rending. I could not figure out where its going wrong.
Please suggest where i m doing wrong.
I suggest to you to separate the WindowForm to a component it's seems that this is the problem.
when I use it as a component the memo start to work
I think is due to this is a function that return component so it's render it no matter what.
the solution:
move WindowForm out side of the component and create a new one with it and then call it and it will work fine
const WindowForm = () => {
return (
<div>
<Row>
<Col span={12}>
<label className={styles.labelWeight}> Name : </label>
<input
type="text"
value={selected.name}
readOnly={true}
className={styles.input}
/>
<br></br>
<br></br>
<label className={styles.labelWeight}>Description : </label>
<input
type="text"
value={selected.description}
readOnly={true}
className={styles.input}
></input>
<br></br>
<br></br>
<input
type="checkbox"
name="runImm"
id="runImm"
checked={isRunNow}
onChange={handleSchedule}
></input>
<label> Schedule as soon as possible</label>
</Col>
<Col span={12}>
<input
type="checkbox"
name="notifyProcess"
id="notifyProcess"
checked={isNotifyMe}
onChange={handleNotify}
></input>
<label> Notify me when this process ends</label>
<br></br>
<br></br>
<label>Submission Notes : </label>
<textarea
name="notes"
id="notes"
rows="4"
cols="50"
disabled={!isNotifyMe}
></textarea>
</Col>
</Row>
<Row>
<Col span={24}>
<Child isRunNow={isRunNow} />
</Col>
</Row>
</div>
);
};
this component and his state to a new component and everything will start to work

React count value of array and calculate total price

The moment an item is selected from the dropdown, the item 'price' of the object is used in the 'countTotalPrice' function. In this function it is the intention that every time an item is selected, the price of the new item is added to the already existing series.
At this time, the function pushes the value to the array, but it constantly overwrites the previous value instead of adding the new value to the previous value.
What I want to achieve is that when someone chooses a treatment and the row is created, all the prices of the created rows are added together to a total amount.
The code:
import React from "react";
import { useState } from 'react';
import { makeStyles } from "#material-ui/core/styles";
import styles from "assets/jss/material-dashboard-react/views/dashboardStyle.js";
import { Container } from "react-bootstrap";
import { Row } from "react-bootstrap";
import { Col } from "react-bootstrap";
import Close from '#material-ui/icons/Close';
import { render } from "react-dom";
const useStyles = makeStyles(styles);
export default function ChaskDesk() {
const employee = ["Robin","Raoul","Joppe "];
const service = [{
id: 1,
name: 'Knippen',
price: 11.00
},
{
id: 2,
name: 'Scheren',
price: 10.00
},
{
id: 3,
name: 'Wassen',
price: 12.00
}]
const counting = [1,2,3,4,5,6];
const gender = ["man", "vrouw", "kind"];
const client = ["Passant"];
const [employeeOrder, setEmployeeOrder] = useState('');
const [serviceOrder, setServiceOrder] = useState([]);
//const serviceOrder = [];
const countingOrder = [];
const genderOrder = [];
const clientOrder = "";
const [payment, setPayment] = useState([]);
//const payment = 0;
const classes = useStyles();
const handelChangeGender = function(event){
genderOrder.push(event.target.value);
};
//this function
const handelChangeService = function(event){
for(var i = 0; i < service.length; i++) {
if (service[i].id == event.target.value) {
setServiceOrder([...serviceOrder,{name: service[i].name, price: service[i].price, id:service[i].id}]);
countTotalPrice(service[i].price);
}
}
};
//this function
const countTotalPrice = function(price){
const counts = [];
counts.push(price);
console.log(counts);
};
const popService = function(event){
setServiceOrder(serviceOrder.filter(item => item.id !== event));
};
const handelChangeEmployee = function(event) {
setEmployeeOrder(event.target.value)
};
return (
<div>
<Container className={classes.containerPixelActive}>
<h3>Afrekenen</h3>
<Row className={classes.tablePixelRow}>
<Col md={8} className={classes.rowChashdesk}>
<form>
<Row>
<Col md={6}>
<label>
Klant:
</label>
<br/>
<select >
{
client.map(function(item, i){
return <option key={i} value={item}>{item}</option>
})
}
</select>
</Col>
</Row>
<Row>
<Col md={6}>
<div className={classes.rowOfForm}>
<label>
Gender:
</label>
<br/>
<select onChange={handelChangeGender}>
{
gender.map(function(item, i){
return <option key={i} value={item}>{item}</option>
})
}
</select>
</div>
</Col>
</Row>
<Row>
<Col md={6}>
<div className={classes.rowOfForm}>
<label>
Behandeling:
</label>
<br/>
<select onChange={handelChangeService}>
{
service.map(function(item){
return <option key={item.id} value={item.id}>{item.name}</option>
})
}
</select>
</div>
</Col>
<Col md={6}>
<div className={classes.rowOfForm}>
<label>
Medewerker:
</label>
<br/>
<select onChange={handelChangeEmployee}>
{
employee.map(function(item, i){
return <option key={i} value={item}>{item}</option>
})
}
</select>
</div>
</Col>
</Row>
{
serviceOrder.map(function(item, i){
console.log(item)
return <Row key={i} >
<Col md={6}>
<div className={classes.rowOfForm}>
<label>
Verkregen behandeling:
</label>
<br/>
<input type="text" name="name" value={item.name}/>
</div>
</Col>
<Col md={2}>
<div className={classes.rowOfForm}>
<label>
Aantal:
</label>
<br/>
<select>
{
counting.map(function(item, i){
return <option key={i} value={item}>{item}</option>
})
}
</select>
</div>
</Col>
<Col md={2}>
<div className={classes.rowOfForm}>
<label>
Prijs:
</label>
<br/>
<input type="text" name="name" value={item.price}/>
</div>
</Col>
<Col md={2}>
<div className={classes.rowIcon}>
<Close size={20} onClick={() => popService(item.id)}></Close>
</div>
</Col>
</Row>
})}
</form>
</Col>
<Col md={3} className={classes.rowChashdesk}>
<h5>Totaal overzicht</h5>
<h6>Medewerker</h6>
<p>{employeeOrder}</p>
<h6>Behandeling</h6>
<ul>
{
serviceOrder.map(function(item, i){
return <li class="listTreatment" key={i}>{item.name}</li>
})
}
</ul>
<h6>Aantal</h6>
<p>{countingOrder}</p>
<h6>Klant</h6>
<p>{clientOrder}</p>
<h6>Te betalen</h6>
<p>{countTotalPrice}</p>
</Col>
</Row>
</Container>
</div>
);
}
Each time the function runs you are making new counts array.
const countTotalPrice = function(price){
const counts = [];
counts.push(price);
console.log(counts);
};
you should declare counts outside this function
please try to decalre it as state
const [counts, setCounts] = useState([]);
//.....
const countTotalPrice = function(price){
let newCounts = counts
newCounts.push(price);
setCounts(newCounts );
console.log(counts);
};

Data from one JSON file is overwriting another JSON dataset when trying to use react-select module in a form in React

Good morning, I have created a new node module by duplicating react-select-country-list found here, https://www.npmjs.com/package/react-select-country-list and modifying the files to display US states instead of countries.
All is well with the new module except for when I go to implement it.
I am trying to build a contact page where users can enter a contact's address with US state(not required) and country.
When I do, the "country" data is overwritten by the "state" data and I do not know the way to differentiate between the countries module and the us states module within my jsx file.
Both country and state dropdowns show US states, the desired behavior is to show countries for the "country" dropdown and US states for the "state" dropdown.
I do not expect there to be any difference between the country dropdown and the state dropdown because I haven't done anything to differentiate between the two because I do not know how.
Will someone please explain to me how I can differentiate from the two modules in my jsx file? Or if there is another/better way to do this please let me know. I am new to React.
Here is my jsx component code:
import React from "react";
import Select from "react-select";
import countryList from "react-select-country-list";
import usstatesList from "react-select-usstates-list";
// reactstrap components
import {
Card,
CardHeader,
CardBody,
CardTitle,
FormGroup,
Form,
Row,
Col
} from "reactstrap";
class AddNewContact extends React.Component {
constructor(props) {
super(props);
this.options = countryList().getData();
this.options = usstatesList().getData();
this.state = {
options: this.options,
value: null
};
}
changeHandler = value => {
this.setState({ value });
};
render() {
return (
<>
<div className="content">
<Row>
<Col md="12">
<Card className="card-user">
<CardHeader>
<CardTitle tag="h5">Add Customer Info</CardTitle>
</CardHeader>
<CardBody>
<Form>
<Row>
<Col className="pl-1" md="6">
<FormGroup>
<label>State</label>
<Select
options={this.state.options}
value={this.state.value}
onChange={this.changeHandler}
/>
</FormGroup>
</Col>
<Col className="pl-1" md="6">
<FormGroup>
<label>Country</label>
<Select
options={this.state.options}
value={this.state.value}
onChange={this.changeHandler}
/>
</FormGroup>
</Col>
</Row>
</Form>
</CardBody>
</Card>
</Col>
</Row>
>
</div>
</>
);
}
}
export default AddNewContact;
You can solve your problem by renaming this.options to this.countryOptions for countries and to this.usStateOptions for US states. In this.state remove options property and use this.countryOptions and this.usStateOptions for your dropdowns. I hope this helps.
Your class should look like this:
class AddNewContact extends React.Component {
constructor(props) {
super(props);
this.countryOptions = countryList().getData();
this.usStateOptions = usstatesList().getData();
this.state = {
value: null
};
}
changeHandler = value => {
this.setState({ value });
};
render() {
return (
<>
<div className="content">
<Row>
<Col md="12">
<Card className="card-user">
<CardHeader>
<CardTitle tag="h5">Add Customer Info</CardTitle>
</CardHeader>
<CardBody>
<Form>
<Row>
<Col className="pl-1" md="6">
<FormGroup>
<label>State</label>
<Select
options={this.usStateOptions}
value={this.state.value}
onChange={this.changeHandler}
/>
</FormGroup>
</Col>
<Col className="pl-1" md="6">
<FormGroup>
<label>Country</label>
<Select
options={this.countryOptions}
value={this.state.value}
onChange={this.changeHandler}
/>
</FormGroup>
</Col>
</Row>
</Form>
</CardBody>
</Card>
</Col>
</Row>
>
</div>
</>
);
}
}

How to independently delete dynamically-added input fields in ReactJS

I'm trying to independently delete dynamic inputs in a form in React. I have a user attribute group, and then user attribute children. I need to be able to dynamically add new user attribute groups and children, but then delete those fields without deleting ALL of the child attributes.
Right now, when I delete a child attribute, it deletes one from EACH user attribute group.
I have a working fiddle here that shows my code: https://codesandbox.io/embed/23kr654w80
import React, { Component } from "react";
import { Button, Input, Row, Col, Form, FormGroup, Label } from "reactstrap";
class OfferCriteria extends Component {
constructor(props) {
super(props);
this.state = {
single: "",
attributeSingle: [{ single: "" }],
child: "",
attributeChild: [{ child: " " }]
};
}
handleNameChange = event => {
this.setState({
name: event.target.value
});
};
handleAddSingleAttribute = () => {
this.setState({
attributeSingle: this.state.attributeSingle.concat([{ name: "" }])
});
};
handleRemoveSingleAttribute = idx => () => {
this.setState({
attributeSingle: this.state.attributeSingle.filter(
(s, sidx) => idx !== sidx
)
});
};
handleAddChildAttribute = () => {
this.setState({
attributeChild: this.state.attributeChild.concat([{ child: "" }])
});
};
handleRemoveChildAttribute = idz => () => {
this.setState({
attributeChild: this.state.attributeChild.filter(sidz => idz !== sidz)
});
};
render() {
return (
<div>
<Row>
<Col lg="10">
<hr />
</Col>
<Col lg="2" className="float-right">
<Button color="success" onClick={this.handleAddSingleAttribute}>
Add Attribute Group
</Button>
</Col>
</Row>
{this.state.attributeSingle.map(() => (
<div>
<br />
<Row>
<Col lg="2">
<Label>User Attributes</Label>
</Col>
<Col lg="3" className="float-left">
<FormGroup check inline>
<Input
className="form-check-input"
type="radio"
id="includeUserAttributes"
name="inline-radios"
value="includeUserAttributes"
/>
<Label
className="form-check-label"
check
htmlFor="inline-radio1"
>
Include
</Label>
</FormGroup>
<FormGroup check inline>
<Input
className="form-check-input"
type="radio"
id="excludeUserAttributes"
name="inline-radios"
value="excludeUserAttributes"
/>
<Label
className="form-check-label"
check
htmlFor="inline-radio2"
>
Exclude
</Label>
</FormGroup>
</Col>
<Col lg="4">
<Input
type="text"
name="text-input"
placeholder="This is parent attribute"
/>
</Col>
</Row>
<br />
<Row>
<Col lg="3">
{this.state.attributeChild.map(() => (
<div className="shareholder">
<Input
type="text"
name="text-input"
placeholder="This is child attribute"
/>
</div>
))}
</Col>
<Col lg="3" className="float-right">
{this.state.attributeChild.map(() => (
<div className="shareholder">
<Button
color="primary"
onClick={this.handleAddChildAttribute}
>
Add Attribute Child
</Button>
<br />
</div>
))}
</Col>
<Col lg="3" className="float-right">
{this.state.attributeChild.map(idz => (
<div className="shareholder">
<Button
color="danger"
onClick={this.handleRemoveChildAttribute(idz)}
>
Remove Attribute Child
</Button>
<br />
</div>
))}
</Col>
</Row>
<hr />
</div>
))}
</div>
);
}
}
export default OfferCriteria;
I need these child attributes to delete ONLY in their parent attribute group, instead of deleting all of them from all the attribute groups.
There are a couple of things going wrong with your code, but I'll focus on your initial question.
The problem is that you use the same array of child for all your groups. In order to be correct, you should include the attributeChild state into the attributeSingle objects :
{
attributeSingle: [
{
single: "",
attributeChild: [
{
child: " "
}
]
}
]
}
That way, children remain independent between groups.

Resources