Модальный компонент React-bootstrap открывает / закрывает все модалы, когда я отображаю список - PullRequest
0 голосов
/ 22 ноября 2018

плохо знаком с программированием, так что извините, если я не правильно формулирую это.Я использую .map для рендеринга и перечисления каждого элемента массива.Для каждого элемента я хочу, чтобы модал открывал / закрывал только конкретный модал, соответствующий каждому элементу в массиве.Однако, когда я нажимаю на кнопку, чтобы открыть модал, каждый из них открывается и закрывается.Я считаю, что это потому, что все модалы установлены на кнопку включения / выключения.Как я могу установить его (с .map value.id или что-то), чтобы открывался и закрывался только конкретный модал?

class DrinkMenu extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = {
            show: false
        };
        this.handleHide = this.handleHide.bind(this);
    }

    handleHide() {
        this.setState({ show: false });
    }

    async componentDidMount() {
        let res = await axios.get('/getAllDrinks')
        this.props.updateDrinkMenu(res.data)
    }

    async addToCart(drinkObj) {
        let res = await axios.post('/addToCart', drinkObj)
        console.log(`Added ${drinkObj.name} to order.`)
    }

    render() {
        let drinkList = this.props.drinkMenu.map((drink) => {
            return (
                <div key={drink.id}>
                    <h5>{drink.name}</h5>
                    <h6>${drink.price}</h6>

                    <span
                        onClick={() => this.setState({ show: true })}
                    >
                        <strong>More Info</strong>
                        <br />
                        <button onClick={() => this.addToCart(drink)}>Add to Order</button>

                    </span>

                    <Modal
                        show={this.state.show}
                        onHide={this.handleHide}
                        container={this}
                        aria-labelledby="contained-modal-title"
                    >
                        <Modal.Header closeButton>
                            <Modal.Title id="contained-modal-title">
                                {drink.name}
                            </Modal.Title>
                        </Modal.Header>
                        <Modal.Body>
                            <p>{drink.sub_category} | ABV {drink.abv}% | {drink.origin}</p>
                            <Col xs={6} md={4}>
                                <Image className="drink-logo" src={drink.logo} thumbnail />
                            </Col>
                            <p className="drink-description"><strong>Description</strong><br />{drink.description}</p>
                            <p href={drink.website}>Website</p>
                        </Modal.Body>
                        <Modal.Footer>
                            <Button onClick={this.handleHide}>Close</Button>
                        </Modal.Footer>
                    </Modal>
                </div>
            )
        })

        return (
            <div>
                <h2>Drink Menu</h2>
                <div>
                    {drinkList}
                </div>
            </div>
        )
    }
}

1 Ответ

0 голосов
/ 22 ноября 2018

Из кода, которым вы поделились, я вижу, что вы обрабатываете все Model с одинаковым значением состояния, то есть show.Это приводит к тому, что все состояния для всех Models равны true, следовательно, все они, как показано.

Чтобы решить эту проблему, вы можете извлечь весь ваш компонент в новый класс React, который обладает только функциональностью для отображения Modal в соответствии с независимым состоянием.Таким образом, ваш новый компонент React будет выглядеть примерно так:

class DrinkComponent extends React.Component {
    constructor(props) {
        super(props);
        this.handleHide = this.handleHide.bind(this);
        this.state = {
            show: false,
        }
    }
    handleHide() {
        this.setState({ show: false });
    }
    render() {
        const { drink } = this.props;
        return (<div key={drink.id}>
            <h5>{drink.name}</h5>
            <h6>${drink.price}</h6>
            <span
                onClick={() => this.setState({ show: true })}
            >
                <strong>More Info</strong>
                <br />
                <button onClick={() => this.props.addToCart(drink)}>Add to Order</button>
            </span>
            <Modal
                show={this.state.show}
                onHide={this.handleHide}
                container={this}
                aria-labelledby="contained-modal-title"
            >
                <Modal.Header closeButton>
                    <Modal.Title id="contained-modal-title">
                        {drink.name}
                    </Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <p>{drink.sub_category} | ABV {drink.abv}% | {drink.origin}</p>
                    <Col xs={6} md={4}>
                        <Image className="drink-logo" src={drink.logo} thumbnail />
                    </Col>
                    <p className="drink-description"><strong>Description</strong><br />{drink.description}</p>
                    <p href={drink.website}>Website</p>
                </Modal.Body>
                <Modal.Footer>
                    <Button onClick={this.handleHide}>Close</Button>
                </Modal.Footer>
            </Modal>
        </div>);
    }
}

В этом случае каждый DrinkComponent будет иметь свое независимое состояние отображения и скрытия модели.Теперь нам нужно просто изменить существующую функцию render в DrinkMenu, чтобы отобразить DrinkComponent.Таким образом, ваша render функция будет выглядеть примерно так:

render() {
        let drinkList = this.props.drinkMenu.map((drink) => (<DrinkComponent drink={drink} addToCart={this.addToCart}/>));
        return (
            <div>
                <h2>Drink Menu</h2>
                <div>
                    {drinkList}
                </div>
            </div>
        )
    }

Также вы можете удалить шоу state из DrinkMenu, так как оно там не понадобится.Надеюсь, это поможет.

...