2017-09-06 94 views
0

我已经看过类似这样的其他问题,但似乎无法来解决我的问题: 我有两个组成部分:CardContainer.js和SingleCardContainer.js遇到了两个孩子使用相同的密钥ReactJS

CardContainer.js

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

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

var dataRef = firebaseApp.database(); 
var dataArray = []; var userInfo = {}; 
var userArray = []; 
var done = false; 

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

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

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

    componentWillMount() { 
     //Get the data 
     var referThis = this; 
     var videosRef = dataRef.ref('posts/'); 
     videosRef.on('value', function (snapshot) { 
      snapshot.forEach(function (data) { 
       //Store each value into an name-based object. 
       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; 
       userInfo.uniqueKey = data.key; 
       //Then push the object into an array. 
       userArray.push(userInfo); 
       //reset the userInfo object 
       userInfo = {}; 
      }) 
      referThis.setState({ 
       usedArray: userArray 
      }) 
     }); 
    } 


    render() { 
     function initApp() { 
     } 
     window.addEventListener('load', function() { 
      initApp() 
     }); 

     var usedArray = this.state.usedArray; 

     return (
      <div id="bodyType"> 
       {usedArray.map(data => <SingleCardContainer {...data} key={data.uniqueKey} />) 
       } 
      </div> 
     ); 
    } 
} 
export default CardContainer; 

而这里的SingleCardContainer.js:

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

import { firebaseApp } from '../firebase/Firebase'; 
var databaseRef = firebaseApp.database(); 

class SingleCardContainer extends Component { 
    constructor(props) { 
     super(props); 
     this.state = ({ 
      activeUser: false, 
      activeUserID: "", 
      like: false, 
      dislike: false, 
      challenge: false 
     }); 
     this.likeButton = this.likeButton.bind(this); 
     this.componentWillMount = this.componentWillMount.bind(this); 
     this.statCheck = this.statCheck.bind(this); 
    } 

    /** 
    * Use the unique key of each post to distinguish from one another. 
    * 
    */ 
    likeButton(uniqueKey) { 
     var likeNumber, referThis = this, newLikeNumber; 
     if (this.state.activeUser) { 
      databaseRef.ref('posts/' + uniqueKey).on('value', function (snapshot) { 
       likeNumber = snapshot.val().likes; 
      }); 
      databaseRef.ref('statkeeper/' + this.state.activeUserID + '/' + uniqueKey).on('value', function (snapshot) { 
       console.log("StatKeeper: " + snapshot.val().like + "\n" + snapshot.val().dislike + "\n" + snapshot.val().challenge); 
       if (!(snapshot.val().like)) { 
        //increment the number by 1. 
        newLikeNumber = likeNumber + 1; 
       } else { 
        newLikeNumber = likeNumber - 1; 
       } 
      }); 
      setInterval(function() { 
       var updates = {}; 
       updates['posts/' + uniqueKey + '/likes'] = newLikeNumber; 
       //Update it in the database 
       databaseRef.ref().update(updates); 
      }, 2000); 

     } else { 
      //They have not logged in so tell them to log in. 
      window.alert('Please log in to like!'); 
     } 
    } 
    //Check if the user is logged in and then setState if he/she is. If not, they won't be able to like/dislike/challenge. 
    componentWillMount() { 
     //assign state to referThis 
     var referThis = this; 
     firebaseApp.auth().onAuthStateChanged(function (user) { 
      if (user) { 
       referThis.setState({ 
        activeUser: true, 
        activeUserID: user.uid 
       }) 
      } else { 
       referThis.setState({ 
        activeUser: false 
       }) 
      } 
     }); 
    } 
    /** 
    * Check if the user has already liked/disliked/challenged the post's user. 
    */ 

    render() { 
     const { userid, likes, dislikes, challenges, profilePic, videoCategory, videoDesc, videoTitle, videoURL, uniqueKey } = this.props; 
     return (
      <div className="container"> 
       <div className="card" id="generalCard"> 
        <div className="card-text"> 
         <div id="singleVideoContainer"> 
          <h3>{videoTitle}</h3> 
          <p> {userid}</p><p>{uniqueKey}</p> 
          <Player poster="" src={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(this.props.uniqueKey)} role="button"><i className="fa fa-thumbs-up"></i></a> 
             <p id="likeNumber" >{likes}</p> 
            </div> 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
             <a className="supportButtons" onClick={() => this.challengeButton()} role="button"><i className="fa fa-shield"></i></a> 
             <p id="challengeNumber">{challenges}</p> 
            </div> 
            <div className="col-md-4 col-xs-6 col-sm-4"> 
             <a className="supportButtons" onClick={() => this.dislikeButton()} role="button"><i className="fa fa-thumbs-down"></i></a> 
             <p id="dislikeNumber">{dislikes}</p> 
            </div> 
           </div> 
           <div id="commentSection"> 
            <p>{videoCategory}</p> 
           </div> 
          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
     ); 
    } 
} 

export default SingleCardContainer; 

的问题是:我每次点击Like按钮,这个弹出:

flattenChildren(...):遇到了两个带有相同键的孩子。子钥匙必须是唯一的;当两个孩子分享一把钥匙时,只有第一个孩子会被使用。 在CardContainer.js

我试图使钥匙= {this.uniquekey + UNIQUEID}这是我在另一篇文章中看到,但不解决它。

回答

1

这不一定是推荐的,但它可以快速解决您的问题。

修改您的地图以包含索引并将其附加到您的ID。

{ usedArray.map((data, i) => <SingleCardContainer {...data} key={data.uniqueKey+i} />) } 

长期来看,你应该试着找出为什么你的uniqueKey不是那么独特。

+0

嘿克里斯托弗,感谢您的快速解决!此外,uniqueKey是唯一的,为了测试这一点,我在CardContainer'{usedArray.map(data => console.log(data.uniqueKey)}'中做了这个,它在第一次渲染时打印出唯一的键值,并且每当我按下likeButton,它会再次打印出来,你知道为什么会发生这种情况吗?我想我有一个线索,但不知道.. – Bazooka

+0

嘿克里斯托弗,我认为你的解决方案可能存在问题,现在发生的情况是,每当一个国家值更改后,它会再次呈现相同的视频并将其添加到页面上已有的视频中。应该只是在页面上重新呈现视频,而不是再次添加相同的内容。 – Bazooka

相关问题