尝试在另一个组件内部渲染组件时,道具将变为未定义

时间:2017-07-10 15:45:46

标签: javascript reactjs redux rendering

我正在尝试在BookList组件中渲染ProfilePage组件,但我遇到了一个我似乎无法自行解决的问题,主要是因为我不是总之,原因是什么。
这是ProfilePage组件:

import React from 'react';
import { connect } from 'react-redux';
import { getUser, deleteBook } from '../actions/actions';
import { addFlashMessage } from '../actions/flashMessages';
import BookList from './BookList';

class ProfilePage extends React.Component {

    componentWillMount = () => {
        // Get user data by username
        this.props.getUser(this.props.match.params.username)
            .catch(err => {
                this.props.addFlashMessage({
                    type: 'error',
                    text: err.response.data.error,
                })
            });
    };

    render() {
        const { picture, name, email, books } = this.props.profileUser;
        console.log(picture, name, email, books);
        const whenOwner = (
            <div className="extra">
                <div className="ui right floated primary button">
                    Edit
                    <i className="right edit icon"></i>
                </div>
            </div>
        );
        return (
            <div className="ui items">
                <div className="item">
                    <div className="ui small image">
                        <img src={picture || 'https://semantic-ui.com/images/wireframe/image.png'} alt="Profile picture"/>
                    </div>
                    <div className="content">
                        <div className="header">
                            {name}
                        </div>
                        <div className="description">
                            <p>{email}</p>
                        </div>
                        {this.props.currentUser && whenOwner}
                    </div>
                </div>
                {/*<BookList books={books} deleteBook={this.props.deleteBook}/>*/}
            </div>
        )
    }
}

function mapStateToProps(state) {
    if(state.auth.isAuthenticated) {
        return {
            currentUser: state.auth,
            profileUser: state.user
        }
    } else {
        console.log(state);
        return {
            profileUser: state.user
        }
    }
}

React.propTypes = {
    profileUser: React.PropTypes.object.isRequired,
    currentUser: React.PropTypes.object,
};


export default connect(mapStateToProps, { getUser, addFlashMessage, deleteBook })(ProfilePage);

BookList被注释掉时,页面渲染就好了。 BookList的相关道具也在那里。但是,一旦我取消注释BookList,我就会收到booksthis.props.profileUser.books)未定义的错误。 这是React抛出的确切错误:

TypeError: Cannot read property 'map' of undefined
BookList
C:\Users\erody\WebstormProjects\book_trading_club\src\components\BookList.js:16

我怀疑BookList组件本身是否存在问题,因为我在其他地方使用它并且它在那里工作正常。但无论如何它在这里:

import React from 'react';
import BookCard from './BookCard';

const BookList = ({books, deleteBook}) => {

    console.log(books);

    const emptyMessage = (
        <p>
            There are no books.
        </p>
    );

    const bookList = (
        <div className="ui five cards">
            { books.map(book => <BookCard deleteBook={deleteBook} book={book} key={book._id}/>)}
        </div>
    );

    return (
        <div>
            {books.length ? bookList : emptyMessage}
        </div>
    )
};

BookList.propTypes = {
    books: React.PropTypes.array.isRequired,
    deleteBook: React.PropTypes.func.isRequired
};

export default BookList;

通过Redux devtools查看一切似乎都很好。调度操作并正确更新状态 如果我添加动作和相关的减速器会有所帮助,我也可以添加它们,我只是不想让这个帖子太长。

1 个答案:

答案 0 :(得分:1)

问题是您在声明bookList对象时尝试映射books对象。并且您尝试在不验证书籍是否定义的情况下执行此操作。

所以,这个工作流程:

  1. 声明bookList - &gt;试图映射书籍对象
  2. 返回 - &gt;验证books.length&gt; 0 - &gt;渲染的东西
  3. 您的代码的解决方案可以是:

    const bookList = books && books.length ? (
        <div className="ui five cards">
            { books.map(book => <BookCard deleteBook={deleteBook} book={book} key={book._id}/>)}
        </div>
    ) : emptyMessage;
    
    return (
        <div>
            {bookList}
        </div>
    );