2017-08-27 155 views
0

我有两个组件: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; 

我想呈现SingleCardContainer通过传递来自dataArray的信息作为道具。每个用户有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

你应该把任何数据调用到componentDidMount从未render。另请注意,您可以简单地使用map将快照数组转换为值。然后致电setState,最终会用新数据呼叫render

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> 
     ); 
    } 
} 

下面我有一个工作的代码片段,我剥出火力地堡,用硬编码的数据替换它来证明,这将与之反应工作。

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>

不过,我不熟悉火力地堡,所以你碰上会由于数据从火力地堡来,我不拥有控制权,可能需要不同的任何错误题。

+0

嗨Styfle,你的回答完美无缺!之所以花费这么长时间来接受它是因为我无法弄清楚如何在firebase函数中使用“this.setState”(它不会直接让你),所以我不得不将它分配给首先是本地变量,我昨晚想到了。谢谢! – 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

相关问题