Как сделать всплывающее окно для конкретного элемента в реагировать? - PullRequest
0 голосов
/ 23 июня 2019

У меня есть список элементов, и для каждого элемента (.item-wrapper) я хочу получить всплывающее окно с уникальным videoId.

Я подготовил для этого компонент videoPopup, но для каждого элемента я получаю последний массив 'videoId' of 'elements' (тот же videoId для каждого элемента).

С другой стороны, когда я не использую компонент PopupVideo и просто зацикливаюсь на элементах iframes, я получаю правильный идентификатор для конкретного элемента - это только для целей тестирования. (Закомментированная строка)

Я новичок в React, поэтому я знаю, что проблему также очень легко решить.

Спасибо!

Код для отображения предметов:


class Training extends Component {
  constructor(props) {
    super(props);
    this.state = {
      popupShowed: false
    };
  }

  togglePopup = event => {
    this.setState({
      popupShowed: !this.state.popupShowed
    });
  };

  onClosePopup = () => {
    this.togglePopup();
  };

  content = () => {
    const elements = ["76979871", "72675442", "337398380"];

    const items = [];

    for (const [index, value] of elements.entries()) {
      items.push(
        <div className="item-wrapper d-flex mb-4" key={index}>
          <div className="item-col training-num text-white font-weight-normal d-flex align-items-center justify-content-center">
            <span>{index < 10 ? "0" + index : index}</span>
          </div>
          <div className="item-col desc-col">
            <h3 className="text-white title font-weight-normal">
              Dlaczego warto?
            </h3>
            <div className="text-wrapper training-desc text-white">
              <p>
                Dowiesz się dlaczego Social Media Ninja to Zawód Przyszłości.
                Dostaniesz wiedzę na temat oferowania i briefowania klientów i
                dowiesz się jak zarabiać na social mediach.
              </p>
            </div>
          </div>
          <div className="item-col text-white time-col">
            <div className="inside-wrapper">
              <p className="text-nowrap">
                <strong>Czas trwania:</strong> 2:25:00
                <br />
                <strong>Twój postęp:</strong> 90%
              </p>
            </div>
          </div>
          <div className="item-col play-col d-flex align-items-center justify-content-center d-flex align-items-center justify-content-center">
            <div className="play-wrapper" onClick={this.togglePopup}>
              <svg
                enableBackground="new 0 0 60.001 60.001"
                viewBox="0 0 60.001 60.001"
                xmlns="http://www.w3.org/2000/svg"
                className="play-button"
              >
                <path d="m59.895 58.531-29-58c-.34-.678-1.449-.678-1.789 0l-29 58c-.155.31-.139.678.044.973.182.294.504.474.85.474h58c.347 0 .668-.18.851-.474.182-.295.199-.663.044-.973zm-57.277-.553 27.382-54.764 27.382 54.764z" />
              </svg>
              <span className="text-white mt-2 d-inline-block">zobacz</span>
              {/* <iframe src={'https://player.vimeo.com/video/' + value} width="500" height="600" frameBorder="0" allowFullScreen mozallowfullscreen="true" allowFullScreen></iframe> */}
            </div>
          </div>
          {this.state.popupShowed ? (
            <PopupVideo videoId={value} closePopup={this.onClosePopup} />
          ) : null}
        </div>
      );
    }

    return <div className="list-wrapper">{items}</div>;
  };
  render() {
    return <Layout content={this.content()} />;
  }
}

export default Training;

Код для отображения popupVideo:

class PopupVideo extends Component {
  componentDidMount = () => {
    var iframe = document.querySelector("iframe");
    var player = new Player(iframe);

    player.on("play", function() {
      console.log("played the video!");
    });
  };

  render() {
    return (
      <div className="popup video-popup">
        <div className="popup-inner d-flex align-items-center d-flex justify-content-center">
          <div className="video">
            <span
              onClick={this.props.closePopup}
              className="close-video d-flex align-items-center justify-content-center"
            >
              <img
                src="https://rahimblak.com/images/video-close.png"
                alt="close video"
              />
            </span>
            <div className="embed-container">
              <iframe
                src={
                  "https://player.vimeo.com/video/" +
                  this.props.videoId +
                  "?api=1&amp;autoplay=0#t=0"
                }
                title="Nazwa szkolenia"
                frameBorder="0"
                allowFullScreen
                mozallowfullscreen="true"
                allowFullScreen
              ></iframe>
            </div>
            <div className="video-nav">
              <div className="video-progress"></div>
              <div className="d-flex align-items-center py-4">
                <div className="play">
                  <span className="play-video"></span>
                </div>
                <div className="stop">
                  <span className="stop-video"></span>
                </div>
                <div className="volume">
                  <span className="volume-video"></span>
                </div>
                <div className="time">00:00 / 05:50</div>
                <div className="break"></div>
                <div className="title">
                  <h4>
                    <strong className="mr-3 pr-3">01</strong>Dlaczego warto ?
                  </h4>
                </div>
                <div className="button">
                  <button className="btn btn-secondary d-flex justify-content-center text-uppercase text-light font-weight-bold px-4">
                    Zobacz następny
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default PopupVideo;

У меня нет сообщений об ошибках в консоли.

1 Ответ

0 голосов
/ 23 июня 2019

Хорошо, поэтому я упростил компоненты, чтобы показать вам хороший шаблон для решения подобных проблем.

Сначала создайте VideoContainer для хранения всех videoIds в state.

Мы собираемся вернуть массив Video компонентов и передать videoId в качестве реквизита каждому из них.

Этот контейнер будет отвечать только за предоставление данных другим компонентам

class VideoContainer extends Component {
  state = {
    videoIds: ["76979871", "72675442", "337398380"]
  };

  renderVideo = videoId => <Video key={videoId} videoId={videoId} />

  render() {
    const { videoIds } = this.state;
    return videoIds.map(this.renderVideo);
  }
}

Затем создайте компонент Video, который будет содержать popupShowed в state и будет включать компонент PopupVideo только тогда, когда popupShowed равен true с использованием && передачи в videoId и togglePopup обработчик как props.

Теперь каждый Video является независимым компонентом, который содержит state для отображения PopupVideo

class Video extends Component {
  state = {
    popupShowed: false
  };

  togglePopup = () => {
    this.setState(prevState => ({
      popupShowed: !prevState.popupShowed
    }));
  };

  render() {
    const { popupShowed } = this.state;
    const { videoId } = this.props;

    return (
      <div className="item-wrapper d-flex mb-4">
        <button onClick={this.togglePopup}>Show Popup</button>
        {popupShowed && (
          <PopupVideo videoId={videoId} closePopup={this.togglePopup} />
        )}
      </div>
    );
  }
}

И последний PopupVideo

const PopupVideo = ({ videoId, closePopup }) => (
  <div className="popup video-popup">
    <span onClick={closePopup}>
      <img
        src="https://rahimblak.com/images/video-close.png"
        alt="close video"
      />
    </span>
    <div className="embed-container">
      <iframe
        src={
          "https://player.vimeo.com/video/" +
          videoId +
          "?api=1&amp;autoplay=0#t=0"
        }
        title="Nazwa szkolenia"
        frameBorder="0"
        allowFullScreen
        mozallowfullscreen="true"
      />
    </div>
  </div>
);

песочница

...