Почему мои реквизиты не передаются моему дочернему компоненту? - PullRequest
0 голосов
/ 09 мая 2019

Я пытаюсь создать модал в React, который отображает некоторую информацию при нажатии button в App.js.

Когда я поместил модальный код в App.js, он успешно заполнил данные (хотя и для каждого li сразу).

Я переместил модал в его собственный компонент, но я получаю Cannot read property 'name' of undefined.

Вот мой код App.js:

const APIURL = 'https://api.openbrewerydb.org/breweries?';
const citySearch = 'by_city=boston';

class App extends Component {
  constructor(props) {
    super(props)

    this.handleShow = this.handleShow.bind(this);
    this.handleClose = this.handleClose.bind(this);

    this.state = {
      error: null,
      isLoaded: false,
      breweries: [],
      show: false
    };
  }

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

  handleShow() {
    this.setState({ show: true });
  }

  componentDidMount() {
    fetch(APIURL + citySearch)
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            breweries: result
          });
        },
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {
    const { error, isLoaded, breweries } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
    return (
      <div>
        <ul>
        {breweries.map(brewery => (
          <div className="brewery-card">
          <li key={brewery.id}>
          <p id="brewery-name">{brewery.name}</p>
          <p id="brewery-type">{brewery.brewery_type}</p> 
          <p id="brewery-address">{brewery.street} {brewery.city}, {brewery.state} {breweries.postal_code} </p>
          <button onClick={this.handleShow}>Details</button>
          <a href={brewery.website_url} target="_blank" rel="noopener noreferrer">Visit Site</a>
          </li>
          </div>
        ))}
      </ul>
      <DetailsModal props={this.props.brewery} show={this.state.modalShow} />
      </div>
     );
    }
  }
}

export default App;

А вот мой код компонента, который не получает реквизиты:

import React, { Component } from 'react';
import { Modal, Button } from 'react-bootstrap'

class DetailsModal extends Component {
    constructor(props) {
        super(props);

        this.state = {
            show: false
        };
    }
    render() {

        const brewery = this.props.brewery;

        return (
            <Modal {...this.props}>
            <Modal.Header closeButton>
              <Modal.Title>{brewery.name}</Modal.Title>
            </Modal.Header>
            <Modal.Body>{brewery.street} {brewery.city}, {brewery.state} {brewery.postal_code}</Modal.Body>
            <Modal.Footer>
              <Button variant="secondary" onClick={this.handleClose}>
                Close
              </Button>
            </Modal.Footer>
          </Modal>
        )
    }
}

  export default DetailsModal;

Что мне не хватает, так это то, что я не могу использовать реквизит App.js в DetailsModal.js?

1 Ответ

1 голос
/ 09 мая 2019

Вы передаете реквизиты с неправильным именем (или неправильно обращаетесь к нему)

Это

<DetailsModal props={this.props.brewery} show={this.state.modalShow} />

Должно быть

//              \/ here
<DetailsModal brewery={this.props.brewery} show={this.state.modalShow} />

Когда вы делаете const brewery = this.props.brewery;вы пытаетесь получить доступ к brewery из реквизита, но вы не указали brewery в реквизите, только props и show.

Вот пример, чтобы прояснить, что происходит.

Здесь вы передаете someProp ComponentX

Внутри ComponentX this.props будет объектом с переданными реквизитами, и в этом случае это будет

{
    someProp: "something"
}

Итак this.props.someProp возврат "something"

Если вы попытаетесь получить доступ к this.props.someOtherPropвернется undefined.И если вы попытаетесь получить доступ к this.props.someOtherProp.X, вы получите ошибку annot read property 'X' of undefined

Если у вас возникли проблемы, чтобы понять, как работает реквизит, пожалуйста, посмотрите examples из документации.

Редактировать:

Другая причина, по которой вы получаете ошибку, состоит в том, что в App this.props.brewery не существует.

В вашем состоянии находится только то, что относится к brewery или breweries.

Так что это еще одна ошибка.И вам нужно указать, что вы хотите отобразить в DetailsModal

Редактировать 2:

Чтобы отобразить пивоварню, когда вы щелкаете по ней, вам нужно сохранять в состоянии значение нажатойпивоваренный завод и передать его модальному

  1. Добавить в App состояние currentBrewery

    this.state = {
        error: null,
        isLoaded: false,
        breweries: [],
        show: false,
        currentBrewery: {}
    };
    
  2. Добавить в onClickустановить currentBrewery как brewery из breweries

    <button onClick={() => this.handleShow(brewery)}>Details</button>
    

    И

    handleShow(brewery) {
        this.setState({ show: true, currentBrewery: brewery });
    }
    
  3. Дать DetailsModal currentBrewery, то естьв вашем штате

    <DetailsModal brewery={this.state.currentBrewery} show={this.state.modalShow} />
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...