I have a list of items mapped to be displayed on my “allItems” page. Now every Item has a button that fires up a modal with the specs of the item, but this modal display the same value for all the item (the last one in the array). I tried to pass the id in toggle func but it doesn’t work.
Anyone knows how can I display the same data in the Card and the Modal?
Here’s my code:
JavaScript
x
65
65
1
state = {
2
modal: false,
3
}
4
5
toggle = () => {
6
this.setState({
7
modal: !this.state.modal
8
})
9
}
10
render(){
11
return(
12
{rooms.map(({ _id, name, descr, prezzo }) => (
13
<>
14
<Card key={_id} className="rooms-card-template">
15
<CardImg />
16
<CardBody>
17
<CardTitle>{name}</CardTitle>
18
<CardText>{descr}</CardText>
19
<CardSubtitle>{prezzo}$/notte</CardSubtitle>
20
<Button onClick={this.toggle}>Apri Annuncio</Button>
21
22
<Modal isOpen={this.state.modal} toggle={this.toggle}>
23
<ModalHeader >{name}</ModalHeader>
24
<ModalBody>
25
{descr}
26
<h5 style={{ paddingTop: "10px"}}>Riepilogo prenotazione</h5>
27
<Form>
28
<FormGroup>
29
<Label>Struttura:</Label>
30
<Input value={name}/>
31
</FormGroup>
32
<FormGroup>
33
<Label>Ospiti:</Label>
34
<Input type="select"name="ospiti" id="ospiti">
35
<option>1</option>
36
<option>2</option>
37
<option>3</option>
38
<option>4</option>
39
<option>5</option>
40
<option>6</option>
41
<option>7</option>
42
<option>8</option>
43
<option>9</option>
44
</Input>
45
</FormGroup>
46
<FormGroup>
47
<Label>Check in</Label>
48
<Input type="date" name="checkin-date" id="checkin-date" placeholder="Check in" />
49
</FormGroup>
50
<FormGroup className="rooms-checkout">
51
<Label>Check out</Label>
52
<Input type="date" name="checkout-date" id="checkout-date" placeholder="Check out" />
53
</FormGroup>
54
{ isAuth ? userAuth : userUnauth }
55
</Form>
56
</ModalBody>
57
</Modal>
58
</CardBody>
59
</Card>
60
61
</>
62
))}
63
)
64
}
65
Advertisement
Answer
Issue
You’ve a single boolean modal
state that all the modals cue from. When this.state.modal
is true then a modal is rendered and opened for each element being mapped.
Solution
Instead of storing a boolean value for whether or not a modal should be open you should store an id
when you want a specific modal to open.
JavaScript
1
37
37
1
state = {
2
modal: null // <-- null, non-id state value
3
};
4
5
toggle = (id) => () => { // <-- curried function handler
6
this.setState((prevState) => ({
7
modal: prevState.modal === id ? null : id // <-- set new id or toggle off
8
}));
9
};
10
11
render() {
12
return (
13
<>
14
{rooms.map(({ _id, name, descr, prezzo }) => (
15
<Card key={_id} className="rooms-card-template">
16
17
<CardBody>
18
19
<Button
20
onClick={this.toggle(_id)} // <-- pass id
21
>
22
Apri Annuncio
23
</Button>
24
25
<Modal
26
isOpen={this.state.modal === _id} // <-- open if id is match
27
toggle={this.toggle(_id)} // <-- pass id
28
>
29
30
</Modal>
31
</CardBody>
32
</Card>
33
))}
34
</>
35
);
36
}
37