【问题标题】:How can I render Parent component again after update from the child component从子组件更新后如何再次渲染父组件
【发布时间】:2021-06-23 06:49:24
【问题描述】:

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

我有一个父组件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>
        );
    }
}

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

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

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

【问题讨论】:

  • 所以如果我理解正确的话,你想在 PUT 到 /admin/update-quiz 成功后在 QuizEdit 中重新获取测验列表。在这种情况下,在 QuizManagement 父组件中,将 componentDidMount axios 调用放在一个单独的函数中,并将其作为道具传递给 QuizEdit。然后在QuizEdit,在提交axios调用的回调中,可以调用那个函数
  • 也许这就是我想要的,因为我真的不知道该怎么做,所以我不确定我的想法是否正确,我会试试你的,看看它是否有效或不是,谢谢你给我一些方法。
  • 哦,但是如果我把componentDidMount放在函数里面,它不会在第一时间为我呈现测验列表,所以表格中不会显示任何数据让我编辑...
  • 没关系,我也修好了!我现在很高兴:)
  • @Bunny 您能否将解决方案发布为答案,以便其他人可以看到您是如何解决的?

标签: reactjs


【解决方案1】:

我已经根据@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()}
    />

这将传递props 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再次运行,这将与子组件交互时立即渲染组件。

【讨论】:

    猜你喜欢
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 2019-02-26
    • 2018-08-12
    相关资源
    最近更新 更多