遇到两个孩子,使用相同的密钥ReactJS

时间:2017-09-06 01:41:46

标签: javascript arrays reactjs render

我已经查看了与此类似的其他问题,但似乎无法解决我的问题: 我有两个组件:CardContainer.js和SingleCardContainer.js

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

我已尝试制作我在另一篇文章中看到的key = {this.uniquekey + uniqueid},但这并没有解决它。

1 个答案:

答案 0 :(得分:0)

不一定建议这样做,但它可以快速解决您的问题。

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

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

从长远来看,您应该尝试找出uniqueKey不那么独特的原因。