在迭代中将状态作为道具传递给另一个组件

时间:2017-08-27 22:00:53

标签: javascript html arrays reactjs

我有两个组件: CardContainer SingleVideoContainer 。 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中的信息作为props传递来呈现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;

1 个答案:

答案 0 :(得分: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>
        );
    }
}

下面我有一个正常工作的代码片段,我删除了Firebase并用硬编码数据替换它,以证明这可以与React一起使用。

&#13;
&#13;
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'));
&#13;
<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>
&#13;
&#13;
&#13;

但是,我对Firebase并不熟悉,因此您遇到的任何错误都归因于来自Firebase的数据,我无法控制并可能需要不同的问题。