更新状态中断子提升组件

时间:2017-11-22 12:17:24

标签: reactjs

我仍然试图处理父子数据共享,并且遇到一个问题,我的有状态组件有一组对象,可以通过componentWillReceiveProps()在我的子道具组件中正确显示,但当我触发我的时候updateCommentsFunc()函数,由子组件表单触发,调用POST并将值附加到数组,但是我的子组件出现undefined错误,表明数据不是流动的状态更新。

我使用了错误的方法吗?我应该向updateCommentsFunc()添加内容吗?

以下是控制台错误:

    Uncaught TypeError: Cannot read property 'picture' of undefined
        at Comment (comment.js?2fa6:15)
        at mountIndeterminateComponent (react-dom.development.js?cada:10400)
        at beginWork (react-dom.development.js?cada:10601)
        at performUnitOfWork (react-dom.development.js?cada:12573)
        at workLoop (react-dom.development.js?cada:12682)
        at HTMLUnknownElement.callCallback (react-dom.development.js?cada:1299)
        at Object.invokeGuardedCallbackDev (react-dom.development.js?cada:1338)
        at invokeGuardedCallback (react-dom.development.js?cada:1195)
        at performWork (react-dom.development.js?cada:12800)
        at scheduleUpdateImpl (react-dom.development.js?cada:13185)

在行触发:

    <img src={props.user.picture} className="comment__record-profile"/>

这是父组件,它被赋予一个对象,该对象的嵌套数组被映射并存储在状态数组中:

    //Loop through JSON and create Comment and Comment Container Component
    class CommentFeed extends React.Component {
        constructor(props){
            super(props);
            this.state = { 
                comments: []
            };
            this.updateCommentsFunc = this.updateCommentsFunc.bind(this);
        }

        //Load Array to component
        componentWillReceiveProps(nextProps){
            let commentArr = [];
            nextProps.comments.map((comment) => {
                comment.comment_comments.map((comment) => {
                    commentArr.push(comment);
                })
            })
            this.setState({comments: commentArr});
        }

        //Append new POST value to commentArr
        updateCommentsFunc(newComments){
            var updatedCommentArr = this.state.comments.slice();
            updatedCommentArr.push(newComments)
            this.setState({comments: updatedCommentArr});
        }

        render(){
            return (
                <div>
                { 
                    this.props.comments.map((comment, index) => {
                        return (
                            <div className="row">
                                <div className="col-md-6 col-md-offset-3 comment-card">
                                    <CommentCard {...comment} key={comment.commentIdHash} user={this.props.user} />
                                    <Comments comments={this.state.comments} key={index} commentId={comment.commentIdHash} csrf={this.props.csrf} updateComments={this.updateCommentsFunc}/> 
                                </div>
                            </div>
                        );
                    })
                }
                </div>
            );
        }
    }

这是将子组件拆分为表单并显示注释:

    //Blog Comment - Container
    export default class Comments extends React.Component {
        render() {
            return (
                <div className="blog-comment-container">
                    <CommentForm updateComments={this.props.updateComments} blogId={this.props.blogId} csrf={this.props.csrf}/>
                    { this.props.comments.map((comment, i) =>
                        <AttachedComment commentObj={comment} blogComponentId={this.props.blogId}/>
                        )}

                </div>
            );
        }
    }

以下是使用POST返回的JSON数据调用this.props.updateComments()的表单:

class CommentForm extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            value: ''
        };

        this.postComment = this.postComment.bind(this);
        this.onChange = this.onChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    postComment(comment, blogId, csrfToken) {
        var body = { comment: comment };
        var route = 'http://localhost:3000/app/blog/' + blogId + '/comment';
        fetch(route, 
            { 
                method: 'POST', 
                body: JSON.stringify(body), 
                headers: { 
                    'X-CSRF-Token': csrfToken,
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                }
            })
            .then(res => {
                return res.json();
            })  
            .then(data => {
                this.props.updateComments(data)
            }) 
            .catch(err => {
                console.log(err);
            });
    }

    onChange(e){
        this.setState({
            value: e.target.value
        });
    }

    handleSubmit(e){
        e.preventDefault();
        this.postComment(this.state.value, this.props.blogId, this.props.csrf);
    }

    render(){
        return (
            <div className="blog-comment__form">
                <div className="row">
                    <div className="col-md-12">
                        <label>Comment:</label>
                    </div>
                </div>
                <div className="row">
                        <form action={"/app/blog/" + this.props.blogId + "/comment"} method="post" onSubmit={this.handleSubmit}>
                            <input type="hidden" name="_csrf" value={this.props.csrf}/>
                            <div className="col-md-9">
                                <textarea name="comment" className="blog-comment__form-text-area" onChange={e => this.setState({ value: e.target.value })} value={this.state.value}></textarea>
                            </div>
                            <div className="col-md-3">
                                <button type="submit" className="blog-comment__form-button" disabled={!this.state.value}>Comment</button>
                            </div>
                        </form>
                </div>
            </div>
        )
    }
}

这是条件,它检查嵌套数组Id是否与父级的fed对象的id匹配:

const AttachedComment = props => {
    if(props.commentObj.blogIdHash == props.blogComponentId){
        return (
            <Comment {...props.commentObj} key={props.commentObj.blogCommentId}/>
            )
    } else {
        return null;
    }
}

最后,如果返回TRUE,则会显示出现错误的组件:

const Comment = props => {
    return (
        <div className="comment-comment__record">
            <div className="row">
                <div className="col-md-12">
                    <div className="comment-comment__meta">
                        <div className="row">
                            <div className="col-md-6">
                                <img src={props.user.picture} className="comment-comment__record-profile"/>
                            </div>
                            <div className="col-md-6">

                            </div>
                        </div>
                    </div>
                    <h5>{props.user_id}</h5>
                    <h4>{props.comment}</h4>
                    <h3>{props.synotate_user.fullNameSlug}</h3>
                </div>
            </div>
        </div>
    )
} 

0 个答案:

没有答案