我认为我在理解状态和道具方面存在一个基本问题……我有一个记录数组,当我console.log该数组时,它返回正确的记录,但是.setState不会更改UI中返回的记录。我想知道是否需要将handleCommentDelete移到父组件?这是父母:

import React from 'react';
import { render } from 'react-dom';

import CommentForm from './CommentForm';
import CommentList from './CommentList';


class CommentBox extends React.Component {
    constructor(props) {
        super(props);
        this.state = { data: [] };
        this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
    }
    componentDidMount() {
        this.loadCommentsFromServer();
        window.setInterval(
            () => this.loadCommentsFromServer(),
            this.props.pollInterval,
        );
    }
    handleCommentSubmit(comment) {
        const comments = this.state.data;
        comment.Id = comments.length + 1;
        const newComments = comments.concat([comment]);
        this.setState({ data: newComments });

        const data = new FormData();
        data.append('Id', comment.Id);
        data.append('Name', comment.Name);
        data.append('Phone', comment.Phone);
        data.append('Email', comment.Email);

        const xhr = new XMLHttpRequest();
        xhr.open('post', this.props.submitUrl, true);
        xhr.onload = () => this.loadCommentsFromServer();
        xhr.send(data);
    }
    loadCommentsFromServer() {
        const xhr = new XMLHttpRequest();
        xhr.open('get', this.props.url, true);
        xhr.onload = () => {
            const data = JSON.parse(xhr.responseText);
            this.setState({ data: data });
        };
        xhr.send();
    }
    render() {
        return (
            <div className="row padBottom_10">
                <div className="col-md-12">
                    <CommentForm onCommentSubmit={this.handleCommentSubmit} />
                </div>
                <div className="col-md-12">
                    <div className="commentBox border borderBorderGrey highlightPrimaryGrey">
                        <CommentList data={this.state.data} />
                    </div>
                </div>
            </div>

        );
    }
}

export default CommentBox;


...这是子组件,我正在尝试删除记录。

import React from 'react';
import { render } from 'react-dom';

class CommentList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: [{}]
        };
        this.handleCommentDelete = this.handleCommentDelete.bind(this);
    }
    handleCommentDelete(id) {
        console.log(this.props.data); // returns n records
        let comments = [...this.props.data];
        this.setState({
            data: comments.filter(comment => comment.Id !== id)
        });
        console.log(comments.filter(comment => comment.Id !== id)); // returns n - 1 records
    }
    render() {
        return (
            <table className="commentList react-bs-table">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Phone</th>
                        <th>Email</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    {
                        this.props.data.map((comment, i) => {
                            return (
                                <tr className="comment" key={i}>
                                    <td className="commentId">{comment.Id}</td>
                                    <td className="commentName">{comment.Name}</td>
                                    <td className="commentPhone">{comment.Phone}</td>
                                    <td className="commentEmail">{comment.Email}</td>
                                    <td className="commentCRUD">
                                        <a onClick={() => this.handleCommentDelete(comment.Id)}>
                                            <i className="fa fa-trash" />
                                        </a>
                                    </td>
                                </tr>
                            );
                        })
                    }
                </tbody>
            </table>
        );
    }
}

export default CommentList;


我真的很想在墙上理解这件事……在此先感谢您的帮助!

最佳答案

handleCommentDelete应该在父组件中。您可以将函数从父级传递给子级作为道具。

将功能传递给子组件

<CommentList data={this.state.data} handleCommentDelete={this.handleCommentDelete} />

父功能

handleCommentDelete = (id) => {
    this.setState({
        data: this.state.data.filter(comment => comment.Id !== id)
    });
}


参考道具功能

<a onClick={() => this.props.handleCommentDelete(comment.Id)}>

当孩子应该只是道具时,您正在混合状态和道具。将handleCommentDelete作为道具传递给孩子,用this.props.handleCommentDelete(id)进行调用,并更新父级中的状态以反映删除。然后,它将使用新的评论列表重新呈现子级。

09-13 03:37