Reputation: 366
I have an array that renders a button and when I click this button I need to only change the item of this array connected to that button, adding the name of the user connected to that localStorage. Currently, when I click the button it is changing all the items in the array. To help, I gave a functional example of what I need at this link: https://codesandbox.io/embed/lots-tojln
I need the buttons to work separately
import React from "react";
import "./styles.css";
const separator = "/";
export default class Card extends React.Component {
constructor(props) {
super(props);
this.state = {
toggleButton: true,
lots: [
{
lotNumber: "1",
lotPrice: "10.00",
lotPriceTax: "0.00",
lotType: "U",
lotUniqueNumber: "xZ38Dw7bDwD33z469xcB4yy3b64D3z",
quantity: 2,
ticketName: "Camarote",
ticketPrevenda: "false",
ticketUniqueNumber: "3WaDBCcawdzyZdAZYBCBz1zb170x47",
total: 20,
totalLotPrice: 10
},
{
lotNumber: "1",
lotPrice: "10.00",
lotPriceTax: "0.00",
lotType: "M",
lotUniqueNumber: "xZ38Dw7bDwD33z469xcB4yy3b64D3z",
quantity: 2,
ticketName: "Camarote",
ticketPrevenda: "false",
ticketUniqueNumber: "3WaDBCcawdzyZdAZYBCBz1zb170x47",
total: 20,
totalLotPrice: 10
}
],
userName: ""
};
this.ticketsCheckDocument = this.ticketsCheckDocument.bind(this);
this.ticketChange = this.ticketChange.bind(this);
}
ticketsCheckDocument(e) {
const [ticketUniqueNumber, lotType, Name] = e.target.value.split(separator);
console.log(ticketUniqueNumber);
console.log(lotType);
console.log(Name);
this.setState({ toggleButton: false });
this.setState({ userName: Name });
}
ticketChange() {
this.setState({ toggleButton: true });
this.setState({ userName: "" });
}
render() {
const lots = this.state.lots.map((lot, l) => (
<div className="box-ticket" key={l}>
<div className="box-vertical">
<h4 className="ticket-type">
{lot.lotType === "U"
? "Unissex"
: lot.lotType === "M"
? "Male"
: "Female"}{" "}
<br />
<small>R$ {lot.lotPrice}</small>
</h4>
</div>
<div className="box-text">
<h4 className="ticket-user-name">{this.state.userName}</h4>
<p className="text-center">
The invitations are nominal. <br />
Please indicate below who will use this invitation
</p>
<div className="box-button">
{this.state.toggleButton ? (
<div>
<button
type="button"
className="btn btn-primary"
value={`${lot.ticketUniqueNumber}${separator}${
lot.lotType
}${separator}Teste ${l}`}
onClick={this.ticketsCheckDocument}
>
It's My
</button>
<button type="button" className="btn btn-primary">
I'll Give
</button>
</div>
) : (
<button
type="button"
className="btn btn-primary"
onClick={this.ticketChange}
>
Change
</button>
)}
</div>
</div>
</div>
));
return <div>{lots}</div>;
}
}
Upvotes: 1
Views: 1181
Reputation: 16122
You can move the whole code a component and let each component manage it's state.
class Invitation extends React.Component {
state = {
toggleButton: true,
userName: '',
}
ticketsCheckDocument = (e) => {
const [ticketUniqueNumber, lotType, Name] = e.target.value.split(separator);
console.log(ticketUniqueNumber);
console.log(lotType);
console.log(Name);
this.setState({ toggleButton: false });
this.setState({ userName: Name });
}
ticketChange = () => {
this.setState({ toggleButton: true });
this.setState({ userName: "" });
}
render() {
const { lot, index } = this.props;
return (
<div className="box-ticket">
<div className="box-vertical">
<h4 className="ticket-type">
{lot.lotType === "U"
? "Unissex"
: lot.lotType === "M"
? "Male"
: "Female"}{" "}
<br />
<small>R$ {lot.lotPrice}</small>
</h4>
</div>
<div className="box-text">
<h4 className="ticket-user-name">{this.state.userName}</h4>
<p className="text-center">
The invitations are nominal. <br />
Please indicate below who will use this invitation
</p>
<div className="box-button">
{this.state.toggleButton ? (
<div>
<button
type="button"
className="btn btn-primary"
value={`${lot.ticketUniqueNumber}${separator}${lot.lotType
}${separator}Teste ${index}`}
onClick={this.ticketsCheckDocument}
>
It's My
</button>
<button type="button" className="btn btn-primary">
I'll Give
</button>
</div>
) : (
<button
type="button"
className="btn btn-primary"
onClick={this.ticketChange}
>
Change
</button>
)}
</div>
</div>
</div>
)
}
}
DEMO
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<style>
.App {
font-family: sans-serif;
text-align: center;
}
.box-ticket {
background-image: url(./images/ticket03.png);
background-repeat: no-repeat;
background-size: 100% 140px;
background-position-x: 1px;
background-color: #000;
}
.box-vertical {
transform: rotate(270deg);
width: 160px;
position: relative;
float: left;
top: 50px;
left: -15px;
text-align: center;
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
}
.box-vertical h3 {
font-size: 20px;
font-weight: bold;
margin-bottom: 0;
}
.box-vertical h4 {
color: #fff;
font-size: 16px;
}
.box-vertical .ticket-type small {
color: #000;
font-weight: bold;
}
.box-ticket .box-text {
height: 140px;
margin-left: 120px;
padding: 5px 10px;
background-color: transparent;
color: #fff !important;
border-bottom-right-radius: 3px;
border-top-right-radius: 3px;
margin-bottom: 10px;
}
.box-ticket .box-text p {
font-size: 12px;
}
.box-text .box-button {
display: flex;
justify-content: center;
align-items: center;
}
.box-text .box-button button {
padding: 5px;
margin: 0;
margin-right: 5px;
background-color: rgba(230, 45, 85, 0.85);
border-color: transparent;
}
.box-text form > button {
padding: 5px;
margin: 0;
margin-right: 5px;
background-color: rgba(230, 45, 85, 0.85);
border-color: transparent;
}
.box-text .box-button .btn-primary:not(:disabled):not(.disabled):active {
background-color: rgba(230, 45, 85, 1);
border-color: transparent;
}
.box-text .box-button .btn:focus {
outline: none;
box-shadow: none;
}
.ticket-user-name {
text-align: center;
margin-top: 5px;
margin-bottom: 5px;
min-height: auto;
height: 15px;
left: -10px;
position: relative;
}
hr {
margin-top: 0;
}
.installments-warning {
color: #737373;
text-align: center;
font-size: 14px;
margin-top: 0.5em;
font-weight: 400;
}
.total-interest {
margin-top: 0.5em;
text-align: center;
font-size: 18px;
color: #737373;
}
</style>
<div id="root"></div>
<script type="text/babel">
class Invitation extends React.Component {
state = {
toggleButton: true,
userName: '',
}
ticketsCheckDocument = (e) => {
const [ticketUniqueNumber, lotType, Name] = e.target.value.split(separator);
console.log(ticketUniqueNumber);
console.log(lotType);
console.log(Name);
this.setState({ toggleButton: false });
this.setState({ userName: Name });
}
ticketChange = () => {
this.setState({ toggleButton: true });
this.setState({ userName: "" });
}
render() {
const { lot, index } = this.props;
return (
<div className="box-ticket">
<div className="box-vertical">
<h4 className="ticket-type">
{lot.lotType === "U"
? "Unissex"
: lot.lotType === "M"
? "Male"
: "Female"}{" "}
<br />
<small>R$ {lot.lotPrice}</small>
</h4>
</div>
<div className="box-text">
<h4 className="ticket-user-name">{this.state.userName}</h4>
<p className="text-center">
The invitations are nominal. <br />
Please indicate below who will use this invitation
</p>
<div className="box-button">
{this.state.toggleButton ? (
<div>
<button
type="button"
className="btn btn-primary"
value={`${lot.ticketUniqueNumber}${separator}${lot.lotType
}${separator}Teste ${index}`}
onClick={this.ticketsCheckDocument}
>
It's My
</button>
<button type="button" className="btn btn-primary">
I'll Give
</button>
</div>
) : (
<button
type="button"
className="btn btn-primary"
onClick={this.ticketChange}
>
Change
</button>
)}
</div>
</div>
</div>
)
}
}
const separator = "/";
class Card extends React.Component {
constructor(props) {
super(props);
this.state = {
toggleButton: true,
lots: [
{
lotNumber: "1",
lotPrice: "10.00",
lotPriceTax: "0.00",
lotType: "U",
lotUniqueNumber: "xZ38Dw7bDwD33z469xcB4yy3b64D3z",
quantity: 2,
ticketName: "Camarote",
ticketPrevenda: "false",
ticketUniqueNumber: "3WaDBCcawdzyZdAZYBCBz1zb170x47",
total: 20,
totalLotPrice: 10
},
{
lotNumber: "1",
lotPrice: "10.00",
lotPriceTax: "0.00",
lotType: "M",
lotUniqueNumber: "xZ38Dw7bDwD33z469xcB4yy3b64D3z",
quantity: 2,
ticketName: "Camarote",
ticketPrevenda: "false",
ticketUniqueNumber: "3WaDBCcawdzyZdAZYBCBz1zb170x47",
total: 20,
totalLotPrice: 10
}
],
userName: ""
};
this.ticketsCheckDocument = this.ticketsCheckDocument.bind(this);
this.ticketChange = this.ticketChange.bind(this);
}
ticketsCheckDocument(e) {
const [ticketUniqueNumber, lotType, Name] = e.target.value.split(separator);
console.log(ticketUniqueNumber);
console.log(lotType);
console.log(Name);
this.setState({ toggleButton: false });
this.setState({ userName: Name });
}
ticketChange() {
this.setState({ toggleButton: true });
this.setState({ userName: "" });
}
render() {
const lots = this.state.lots.map((lot, l) => (<Invitation index={l} lot={lot} key={l} />));
return <div>{lots}</div>;
}
}
ReactDOM.render(<Card />, document.getElementById("root"));
</script>
Upvotes: 1
Reputation: 1146
You need to make userName
and toggleButton
properties of each object in lots
. Then you can pass the index of the lot to the ticketsCheckDocument
to update the corresponding lot element.
Try this:
import React from "react";
import "./styles.css";
const separator = "/";
export default class Card extends React.Component {
constructor(props) {
super(props);
this.state = {
lots: [{
lotNumber: "1",
lotPrice: "10.00",
lotPriceTax: "0.00",
lotType: "U",
lotUniqueNumber: "xZ38Dw7bDwD33z469xcB4yy3b64D3z",
quantity: 2,
ticketName: "Camarote",
ticketPrevenda: "false",
ticketUniqueNumber: "3WaDBCcawdzyZdAZYBCBz1zb170x47",
total: 20,
totalLotPrice: 10,
toggleButton: true,
userName: ""
},
{
lotNumber: "1",
lotPrice: "10.00",
lotPriceTax: "0.00",
lotType: "M",
lotUniqueNumber: "xZ38Dw7bDwD33z469xcB4yy3b64D3z",
quantity: 2,
ticketName: "Camarote",
ticketPrevenda: "false",
ticketUniqueNumber: "3WaDBCcawdzyZdAZYBCBz1zb170x47",
total: 20,
totalLotPrice: 10,
toggleButton: true,
userName: ""
}
],
};
this.ticketsCheckDocument = this.ticketsCheckDocument.bind(this);
this.ticketChange = this.ticketChange.bind(this);
}
ticketsCheckDocument(e, i) {
const [ticketUniqueNumber, lotType, Name] = e.target.value.split(separator);
console.log(ticketUniqueNumber);
console.log(lotType);
console.log(Name);
const lots = [...this.state.lots];
lots[i].toggleButton = false;
lots[i].userName = Name;
this.setState({
lots
})
}
ticketChange() {
this.setState({
toggleButton: true
});
this.setState({
userName: ""
});
}
render() {
const lots = this.state.lots.map((lot, l) => ( <
div className = "box-ticket"
key = {
l
} >
<
div className = "box-vertical" >
<
h4 className = "ticket-type" > {
lot.lotType === "U" ?
"Unissex" :
lot.lotType === "M" ?
"Male" :
"Female"
} {
" "
} <
br / >
<
small > R$ {
lot.lotPrice
} < /small> <
/h4> <
/div> <
div className = "box-text" >
<
h4 className = "ticket-user-name" > {
this.state.userName
} < /h4> <
p className = "text-center" >
The invitations are nominal. < br / >
Please indicate below who will use this invitation <
/p> <
div className = "box-button" > {
lot.toggleButton ? ( <
div >
<
button type = "button"
className = "btn btn-primary"
value = {
`${lot.ticketUniqueNumber}${separator}${
lot.lotType
}${separator}Teste ${l}`
}
onClick = {
e => this.ticketsCheckDocument(e, i)
} >
It 's My <
/button> <
button type = "button"
className = "btn btn-primary" >
I 'll Give <
/button> <
/div>
) : ( <
button type = "button"
className = "btn btn-primary"
onClick = {
this.ticketChange
} >
Change <
/button>
)
} <
/div> <
/div> <
/div>
));
return <div > {
lots
} < /div>;
}
}
Upvotes: 1