2017-08-27 13 views
0

私は2つのコンポーネントを持っています:CardContainerSingleVideoContainerです。 CardContainerには、データベース内のデータに基づいて複数のSingleVideoContainerが含まれます。反復で別のコンポーネントに小道具として渡します

import React, { Component } from 'react'; 
import Modal from 'boron/WaveModal'; 

//Default firebase App 
import * as firebase from 'firebase'; 
import { firebaseApp } from '../firebase/firebase'; 
import SingleCardContainer from '../cards/SingleCardContainer'; 

var dataRef = firebaseApp.database(); 
var dataArray = []; 

class CardContainer extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      userid: "", 
      videoLink: "", 
      likes: "", 
      challenges: "", 
      videoCat: "", 
      videoDesc: "", 
      videoTitle: "", 
      profilePic: "", 
      disikes: "" 
     } 

     this.showModal = this.showModal.bind(this); 
     this.hideModal = this.hideModal.bind(this); 
     this.componentDidMount = this.componentDidMount.bind(this); 
    } 

    showModal() { 
     this.refs.modal.show(); 
    } 
    hideModal() { 
     this.refs.modal.hide(); 
    } 

    componentDidMount() { 
    } 


    render() { 
     function initApp() { 
      var videosRef = dataRef.ref('posts/'); 
      videosRef.on('value', function (snapshot) { 
       snapshot.forEach(function (data) { 
       var userInfo = {}; 
       var userArray = []; 
       //Set up the next user array group 
       //9 items for 1 user. 
       userInfo.userid = data.val().userid; 
       userInfo.likes = data.val().likes; 
       userInfo.dislikes = data.val().dislikes; 
       userInfo.challenges = data.val().challenges; 
       userInfo.profilePic = data.val().profilePic; 
       userInfo.videoCategory = data.val().videoCategory; 
       userInfo.videoDesc = data.val().videoDesc; 
       userInfo.videoTitle = data.val().videoTitle; 
       userInfo.videoURL = data.val().videoURL; 

       //Then save the object in the array 
       userArray.push(userInfo); 
       //change the index to next user. 
        }) 
      }); 
     } 


     /** 
     * This loads when the page loads (right before renders) 
     */ 
     window.addEventListener('load', function() { 
      initApp() 
     }); 

     return (
      <div id="bodyType"> 
      { 
       userArray.map(
        data => <SingleCardContainer 
          userid={data.userid} 
          title={data.title} 
          likes={data.likes} 
          dislikes={data.challenges} 
          videoURL={data.videoURL} 
       />) 

      } 
     </div> 
     ) 
    } 
} 
export default CardContainer; 

dataArrayの情報を小道具として渡して、SingleCardContainerをレンダリングします。各ユーザーには、私が小道具として渡す必要がある9項目があります。 どうすればいいですか? 1はレンダリングできますが、複数のレンダリングはできません。ここで

はSingleCardContainerです:

import React, { Component } from 'react'; 
import { 
    Player, ControlBar, 
    ForwardControl, CurrentTimeDisplay, 
    TimeDivider, VolumeMenuButton, BigPlayButton 
} from 'video-react'; 

import ModalContainer from '../cards/ModalContainer'; 
class SingleCardContainer extends Component { 
    constructor(props) { 
     super(props); 

     this.likeButton = this.likeButton.bind(this); 
     this.challengeButton = this.challengeButton.bind(this); 
     this.dislikeButton = this.dislikeButton.bind(this); 
    } 

    likeButton() { 
    } 
    challengeButton() { 
    } 
    dislikeButton() { 
    } 
    //We will have to pass down the states from CardContainer as props to this so that they get updated in real-time *fingers-crossed* 

    render() { 
     return (
      <div className="container"> 
       <div className="card" id="generalCard"> 
        <div className="card-text"> 
         <div id="singleVideoContainer"> 
          <h3>{this.props.title}</h3><p> {this.props.userid}</p> 
          <Player poster="" src={this.props.videoURL}></Player> 
          <div id="videoInfoSection"> 
           <div className="row" id="buttonContainerRow"> 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
             <a className="supportButtons" onClick={() => this.likeButton()} role="button" href="#"><i className="fa fa-thumbs-up"></i></a> 
             <p>{this.props.likes}</p> 
            </div> 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
             <a className="supportButtons" onClick={() => this.challengeButton()} role="button" href="#"><i className="fa fa-shield"></i></a> 
             <p>{this.props.challenges}</p> 
            </div> 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
             <a className="supportButtons" onClick={() => this.dislikeButton()} role="button" href="#"><i className="fa fa-thumbs-down"></i></a> 
             <p>{this.props.dislikes}</p> 
            </div> 
           </div> 
           <div id="commentSection"> 
            <p>{this.props.videoDesc}</p> 
           </div> 
          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
     ); 
    } 
} 

export default SingleCardContainer; 
+0

コードがないようです。 'dataArray'はどこで宣言されていますか? Reactコンポーネントの定義はどこですか? – styfle

+0

@styfleねえ、私はCardContainerコンポーネントのすべてのコードを追加しました。 – Bazooka

+0

まあ、私はあなたの問題を参照してください....あなたは、レンダリング機能でイベントリスナーを追加すべきではありません。 'window.addEventListener'をクラス外に移動してみてください。また、「SingleCardContainer」の定義はどこですか? – styfle

答えて

0

あなたは決してrendercomponentDidMountに任意のデータの呼び出しを置くべきではありません。また、mapを使用して、スナップショットアレイを値に変換することもできます。次に、setStateに電話をかけ、最終的に新しいデータでrenderを呼び出します。 I以下

import React from 'react'; 
import * as firebase from 'firebase'; 
import { firebaseApp } from '../firebase/firebase'; 

class CardContainer extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { data: [] }; 
    } 

    componentDidMount() { 
     var dataRef = firebaseApp.database(); 
     var videosRef = dataRef.ref('posts/'); 
     videosRef.on('value', (snapshot) => { 
      var data = snapshot.map(o => o.val()); 
      this.setState({ data: data }); 
     }); 
    } 

    render() { 
     const { data } = this.state; 
     return (<div> 
      {data.map(o => <SingleCardContainer {...o} />)} 
     </div>); 
    } 
} 

class SingleCardContainer extends React.Component { 
    constructor(props) { 
     super(props); 
    } 

    render() { 
     const {title, userid, videoURL, videoDesc, likes, dislikes, challenges} = this.props; 
     return (
      <div className="container"> 
       <div className="card" id="generalCard"> 
        <div className="card-text"> 
         <div id="singleVideoContainer"> 
          <h3>{title}</h3> 
          <p>{userid}</p> 
          <p>{videoURL}</p> 
          <div id="videoInfoSection"> 
           <div className="row" id="buttonContainerRow"> 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
             <a className="supportButtons" onClick={console.log} role="button" href="#"><i className="fa fa-thumbs-up"></i></a> 
             <p>{likes}</p> 
            </div> 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
             <a className="supportButtons" onClick={console.log} role="button" href="#"><i className="fa fa-shield"></i></a> 
             <p>{challenges}</p> 
            </div> 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
             <a className="supportButtons" onClick={console.log} role="button" href="#"><i className="fa fa-thumbs-down"></i></a> 
             <p>{dislikes}</p> 
            </div> 
           </div> 
           <div id="commentSection"> 
            <p>{videoDesc}</p> 
           </div> 
          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
     ); 
    } 
} 

私はFirebaseを剥がし、これが反応して動作することを証明するためにハードコーディングされたデータに置き換え作業コードスニペットを持っています。

class CardContainer extends React.Component { 
 
    constructor(props) { 
 
     super(props); 
 
     this.state = { data: [] }; 
 
    } 
 

 
    componentDidMount() { 
 
     const data = [ 
 
      {title: 'Title1', userid:'u1', videoURL:'video1.webm', videoDesc:'desc1', likes: 'like1', dislikes: 'dislike1', challenges: 'challenge1'}, 
 
      {title: 'Title2', userid:'u2', videoURL:'video2.webm', videoDesc:'desc2', likes: 'like2', dislikes: 'dislike2', challenges: 'challenge2'}, 
 
      {title: 'Title3', userid:'u3', videoURL:'video3.webm', videoDesc:'desc3', likes: 'like3', dislikes: 'dislike3', challenges: 'challenge3'}, 
 
      ]; 
 
     this.setState({ data: data }); 
 
    } 
 

 

 
    render() { 
 
     const { data } = this.state; 
 
     return (<div> 
 
      {data.map(o => <SingleCardContainer {...o} />)} 
 
     </div>); 
 
    } 
 
} 
 

 
class SingleCardContainer extends React.Component { 
 
    constructor(props) { 
 
     super(props); 
 
    } 
 

 
    render() { 
 
     const {title, userid, videoURL, videoDesc, likes, dislikes, challenges} = this.props; 
 
     return (
 
      <div className="container"> 
 
       <div className="card" id="generalCard"> 
 
        <div className="card-text"> 
 
         <div id="singleVideoContainer"> 
 
          <h3>{title}</h3> 
 
          <p>{userid}</p> 
 
          <p>{videoURL}</p> 
 
          <div id="videoInfoSection"> 
 
           <div className="row" id="buttonContainerRow"> 
 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
 
             <a className="supportButtons" onClick={console.log} role="button" href="#"><i className="fa fa-thumbs-up"></i></a> 
 
             <p>{likes}</p> 
 
            </div> 
 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
 
             <a className="supportButtons" onClick={console.log} role="button" href="#"><i className="fa fa-shield"></i></a> 
 
             <p>{challenges}</p> 
 
            </div> 
 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
 
             <a className="supportButtons" onClick={console.log} role="button" href="#"><i className="fa fa-thumbs-down"></i></a> 
 
             <p>{dislikes}</p> 
 
            </div> 
 
           </div> 
 
           <div id="commentSection"> 
 
            <p>{videoDesc}</p> 
 
           </div> 
 
          </div> 
 
         </div> 
 
        </div> 
 
       </div> 
 
      </div> 
 
     ); 
 
    } 
 
} 
 

 
ReactDOM.render(<CardContainer />, document.querySelector('div'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script> 
 

 
<div><!--REACT ROOT--></div>

しかし、私はあなたがに実行するすべてのバグが原因私はオーバーコントロールを持っていないと異なるが必要になる場合がありますFirebaseからのデータになりますFirebaseと同様に慣れていませんよ質問。

+0

ちょっとStyfle、あなたの答えは完璧に動作します! firebase関数の中で "this.setState"を使う方法を理解できなかったので(それはあなたに直接任せることはできません)、私はそれをfinalに受け入れるのにずっとかかったのです。私は昨夜考え出したローカル変数を最初に出しました。ありがとうございました! – Bazooka

+0

これは、 'this'はローカル関数スコープ[MDN参照](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)を参照しています。最初に変数を変更するか、 'function'を[Arrow関数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#Arrow_functions)に変更します。これは' videosRef.on私の答えでは。 – styfle

関連する問題