仅当渲染子组件时,我才获得无限循环-ReactJs

时间:2018-08-20 03:45:43

标签: javascript ajax reactjs render infinite-loop

好的,这让我发疯了!必须从头开始重新编码项目,以查明问题出在哪里。

基本上,我正在尝试通过构建一个可以共享流行歌曲的Web应用程序来练习React。所以这是我的组件树(只有重要的组件:App.js-> [Navbar,Posts]->然后在Posts内部,我有Post组件的列表。这是代码:

import React, { Component } from 'react';
import './App.css';
import {BrowserRouter} from 'react-router-dom';
import Navbar from './components/Navigation/Navbar';
import Posts from './containers/Posts/Posts';


class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <div className="App">
          <Navbar />
          <Posts />
        </div>
      </BrowserRouter>
    );
  }
}

export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

import React, { Component } from 'react';
import Post from './Post/Post';
import $ from 'jquery';

class Posts extends Component {
    state = {
        posts: null,
        // addingNewPost: false
    }

    componentDidMount() {
        $.ajax({
            url: 'https://music-blog-app.firebaseio.com/users/user/posts.json',
            success: (response) => {
                //console.log(response); // object of objects
                // converting to array of objects
                const responseArray = Object.keys(response).map(i => response[i]);
                //console.log(responseArray);
                this.setState({
                    posts: responseArray
                })
                // console.log(this.state.posts);
            }
            //error
        });
    }

    // addingNewPostHandler = () => {
    //     this.setState({addingNewPost: true});
    // }

    // cancelNewPostHandler = () => {
    //     this.setState({addingNewPost: false});
    // }

    sharedNewPostHandler = (caption, embedSrcLink) => {

        var newPostToAdd = {
            caption: caption,
            embedSrcLink: embedSrcLink
        }

        var postsToUpdate = this.state.posts.slice();
        postsToUpdate.push(newPostToAdd);

        // $.ajax({
        //     type: 'POST',
        //     url: 'https://music-blog-app.firebaseio.com/users/user/posts.json',
        //     success: (response) => {
        //         console.log(response);
        //         this.setState(prevState =>({
        //             addingNewPost: false,
        //             posts: [...this.state.posts, newPostToAdd]
        //         })); 
        //     } 
        //     // error
        // });
    }

    render() {

        var postsToRender = <p>Nothing here</p>

        console.log(this.state.posts);
        if(this.state.posts) {
            var myPosts = this.state.posts.slice();
        }
        console.log(myPosts);
 
        let render;
        if(myPosts) {
            render = (myPosts.map((post, index) => { return <p>IF I REPLACE THIS BY RENDERING POST component, I get an infinite loop</p>}))
        } else {
            render = <p>still waiting...</p>
        }

        return (
            <div className="container posts-container">
                {/* <p>jsdhfjhd</p>
                {myPosts ? (myPosts.map((post, index) => {
                    // console.log(post)
                    return <Post key={post} caption={this.state.posts[index].caption} embedSrcLink={this.state.posts[index].embedSrcLink} />
                })) : <p>still waiting...</p>} */}
                {render}
            </div>
        ); 
    }
}

export default Posts;

import React, { Component } from 'react';
import './Post.css';
import PosterProfile from '../../../components/PosterProfile/PosterProfile';

const post = (props) => (
    <div className="post">
        <PosterProfile />
        <div className="card" style={{width: '18rem'}}>
            <div className="card-body">
                <h5 className="card-caption">{props.caption}</h5>
                <div className="embed-iframe">
                    <iframe title="embed" src={props.embedSrcLink} width="300" height="380" frameBorder="0" allowtransparency="true" allow="encrypted-media"></iframe>
                </div>
            </div>
            <div className="card-footer">
                <a href="#like" className="card-link link">Like</a>
                <a href="#comment" className="card-link link">Comment</a>
                <a href="#repost" className="card-link link">Repost</a>
            </div>
        </div>
    </div>
)

export default post;

这是问题所在!因此,Posts的render方法中的这段代码:

render = (myPosts.map((post, index) => { return <p>IF I REPLACE THIS BY RENDERING POST component, I get an infinite loop</p>}))

尽快替换为

render = (myPosts.map((post, index) => { 

return <Post key={post} caption={this.state.posts[index].caption} embedSrcLink={this.state.posts[index].embedSrcLink}
}))

顺便说一句,我正在从Firebase数据库获取帖子。 请帮忙 !预先谢谢你:)

1 个答案:

答案 0 :(得分:0)

在react中渲染列表/数组需要您为每个项目添加一个键。从文档: Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity https://reactjs.org/docs/lists-and-keys.html#keys

我相信您的摘要中正在发生的事情是,您正在将键分配为对象而不是字符串。这肯定会导致意外的行为或错误。