从子组件更新后如何再次渲染父组件

时间:2021-06-23 06:49:24

标签: reactjs

就像我刚才提到的问题,在对子组件进行更改后,如何让父组件呈现?昨天问过这个问题,没有人回答我,所以我必须转帖,也许我无法解释。我自己尝试了一些新手方法,但它不起作用。我又来问了。

我有一个 QuizManagement 的父组件,我有一个 QuizEdit 的子组件。我可以成功地在子组件中进行编辑,一切正常。父组件的更新没有得到刷新。我必须手动刷新页面才能再次查看页面更新。我怎样才能立即更新它?

我认为是将子组件的数据传回父组件,匹配父组件的数据,这样就可以改变父组件中的状态,让父组件再次渲染,但是我不知道这如何或是否正确。

请帮帮我,这是代码,我会缩短和删除一些功能,因为它不需要。

父组件,即QuizManagement

    import QuizEdit from "../QuizEdit";
    
    class QuizManagement extends Component {
        constructor(props) {
            super(props);
            this.state = {
                quizList: [],
                showHideEdit: false,
            };
    this.toggleEdit = this.toggleEdit.bind(this);
        }

//- Get the quiz-topic list//
    async componentDidMount() {
            await axios.get("http://localhost:3000/quiz-topics").then((res) => {
                this.setState({
                    quizList: res.data,
                });
            });
        }

//- Just the function for hide and show the edit button //
    toggleEdit(i) {
            if (this.state.showHideEdit === i) {
                this.setState({ showHideEdit: null });
            } else {
                this.setState({ showHideEdit: i });
            }
        }
    render() {
    const { showHideEdit } = this.state;
    return (
                <div className="admin-table">
    <table>
                        <thead>
                            <tr>
                                <th>Quiz ID</th>
                                <th>Quiz Description</th>
                                <th>Quiz Time</th>
                                <th>Action</th>
                            </tr>
                        </thead>
//- Mapping every elements in the quizList//
                        {this.state.quizList.map((element, i) => {
                            return (
                                <tbody key={i}>
                                    <tr>
                                        <td>{element.quiz_ID}</td>
                                        <td>{element.quizname}</td>
                                        <td>{element.quiztime}</td>
                                        <td className="admin-button">
    <button
                                                className="admin-config-button"
                                                onClick={() => this.toggleEdit(i)}
                                            >
                                                Edit
                                            </button>
//- I implement component QuizEdit with toggle hide and show from above//
                                            {showHideEdit === i && (
                                                <QuizEdit
                                                    id={element.key}
                                                    quiz_ID={element.quiz_ID}
                                                    quizList={this.state.quizList}
                                                />
                                            )}
                                        </td>
                                    </tr>
                                </tbody>
                            );
                        })}
                    </table>
                </div>
            );
        }
    }

子组件是QuizEdit - 这是我实现的按钮,当我每次按下按钮时,它会显示一个带有文本字段的小表格以供输入

class QuizEdit extends Component {
    constructor(props) {
        super(props);
        this.state = this.initialState;
        this.quizChange = this.quizChange.bind(this);
        this.submitForm = this.submitForm.bind(this);
    }
    initialState = {
        quiz_ID: this.props.quiz_ID,
        quizname: "",
        quiztime: "",
        quizList: this.props.quizList,
    };

//-Get the quiz based on quizID, so it will fill in the form immediately when I press edit//
    async componentDidMount() {
        await axios
            .get("http://localhost:3000/admin/get-quiz/" + this.props.quiz_ID)
            .then((res) => {
                this.setState({
                    quizname: res.data.quizname,
                    quiztime: res.data.quiztime,
                });
            });
    }

    resetQuiz = () => {
        this.setState(() => this.initialState);
    };

//-The submit button is submitForm i created, I parse quiz into the exact quiz_ID I get from the Axios below to update its name and time based on the ID //
    submitForm = (event) => {
        event.preventDefault();

        const quiz = {
            quizname: this.state.quizname,
            quiztime: this.state.quiztime,
        };

        axios
            .put(
                "http://localhost:3000/admin/update-quiz/" + this.props.quiz_ID,
                quiz
            )
            .then((res) => {
                if (res.data != null) {
                    toast.success(`Quiz edit successfully`);
                    this.setState(this.initialState);
                } else {
                    toast.error(`Failed to edit quiz`);
                }
            });
    };

    quizChange = (event) => {
        this.setState({
            [event.target.name]: event.target.value,
        });
    };
//- It just the render from below with the text input and submit button//
    render() {
        return (
            <div className="admin-table">
                <form
                    className="create-form"
                    onSubmit={this.submitForm}
                    onReset={this.resetRole}
                >
                    <label htmlFor="quizname">Quiz name:</label>
                    <br />
                    <input
                        type="text"
                        id="quizname"
                        name="quizname"
                        placeholder="Enter your quiz name"
                        value={this.state.quizname}
                        onChange={this.quizChange}
                    />
                    <br />
                    <label htmlFor="quiztime">Quiz time:</label>
                    <br />
                    <input
                        type="number"
                        id="quiztime"
                        name="quiztime"
                        placeholder="Enter your quiz name"
                        value={this.state.quiztime}
                        onChange={this.quizChange}
                    />
                    <br />
                    <button type="submit" className="create-button-form">
                        Edit quiz
                    </button>
                    <button type="reset" className="create-button-form">
                        Reset
                    </button>
                    <br />
                </form>
            </div>
        );
    }
}

我想要实现的是如何将测验名称和测验时间更新回父组件或类似的东西,以便它知道组件已更改,因此它将呈现来自父组件的 GET Axios

async componentDidMount() {
                await axios.get("http://localhost:3000/quiz-topics")

或类似的东西,所以它可以在不刷新页面的情况下再次呈现一个带有最新更新的全新列表,我对这最后一步有点棘手,因为我不知道这是否是接近方法正确与否

1 个答案:

答案 0 :(得分:0)

我已经根据@Jayce444 为我提供的方式解决了这个问题

在父组件处,即 QuizManagement

我创建了一个与 componentDidMount 工作方式相同的方法,并将其命名为:

updateQuiz() {
// You can but method to get data or however you need in here //
        axios.get("http://localhost:3000/quiz-topics").then((res) => {
            this.setState({
                quizList: res.data,
            });
        });
    }

然后在切换隐藏和显示编辑按钮处,我将其作为道具传递,即名为 updateQuiz 的方法。

{showHideEdit === i && (
    <QuizEdit
            id={element.key}
            quiz_ID={element.quiz_ID}
            quizList={this.state.quizList}
          //Pass it down as a props here//
            updateQuiz={this.updateQuiz()}
    />

这会将道具updateQuiz(这是上面的一个方法向下传递给孩子,也就是QuizEdit,您可以将孩子的组件放在这里,并将该方法作为您需要的道具传递。

在我的子组件中,QuizEdit

我有一个 submitForm 用作 onSubmit,每当我单击提交按钮时,它都会提交并且方法 submitForm 将运行:

submitForm = (event) => {
        event.preventDefault();

        const quiz = {
            quizname: this.state.quizname,
            quiztime: this.state.quiztime,
        };

        axios
            .put(
                "http://localhost:3000/admin/update-quiz/" + this.props.quiz_ID,
                quiz
            )
            .then((res) => {
                if (res.data != null) {
                    toast.success(`Quiz edit successfully`);
                    this.setState(this.initialState);
                 //You will add a method that we passed as props from the parent component here if the condition run successfully//
                    this.props.updateQuiz();

                } else {
                    toast.error(`Failed to edit quiz`);
                }
            });
    };

这会变成一个回调,比如我们每次按下Edit按钮,如果它运行成功,它会更新,然后回调运行,并且updateQuiz会在父组件被触发再次运行,这将当您与子组件交互时立即渲染组件。