Как я могу снова отобразить родительский компонент после обновления дочернего компонента

#reactjs

Вопрос:

Как и в вопросе, о котором я упоминал, как я могу сделать визуализацию родительского компонента после внесения изменений в дочерний компонент? Я задавал этот вопрос вчера, но мне никто не ответил, поэтому я должен сделать репост, возможно, я не могу это объяснить. Я пробовал некоторые новые способы самостоятельно, но это не работает. Я спрашиваю еще раз.

У меня есть родительский компонент , который есть QuizManagement , у меня есть дочерний компонент, который есть QuizEdit . Я могу успешно выполнить редактирование в дочернем компоненте, все отлично работает. Обновления родительского компонента не обновляются. Мне нужно обновить страницу вручную, чтобы снова увидеть обновление страницы. Как я могу немедленно обновить его?

Я думаю, что передача данных из дочернего компонента обратно в родительский компонент, который соответствует данным родительского компонента, чтобы он мог изменить состояние в родительском компоненте, что заставит родительский компонент снова отображаться, но я не знаю, как и правильно ли это или нет.

Пожалуйста, помогите мне, вот код, я укорочу и вырежу некоторые функции, так как в этом нет необходимости.

Компонент отца, который является управлением викторинами

     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 amp;amp; (
                                                <QuizEdit
                                                    id={element.key}
                                                    quiz_ID={element.quiz_ID}
                                                    quizList={this.state.quizList}
                                                />
                                            )}
                                        </td>
                                    </tr>
                                </tbody>
                            );
                        })}
                    </table>
                </div>
            );
        }
    }
 

The child component is QuizEdit — which is the button I implement, when every time I press the button it’ll display a small table with a text field to input

 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")
 

или что-то в этом роде, чтобы он мог снова отобразить совершенно новый список с последним обновлением без обновления страницы, я немного запутался в своей голове по поводу этого последнего шага, потому что я не знаю, правильный ли это подход или нет

Комментарии:

1. Так что, если я вас правильно понял, вы хотите повторно получить список тестов после того, как поставите, чтобы /admin/update-quiz добиться успеха QuizEdit . В этом случае внутри QuizManagement родительского компонента поместите этот componentDidMount вызов axios в отдельную функцию и передайте его в QuizEdit качестве опоры. Затем в QuizEdit , в обратном вызове для отправки вызова axios, вы можете вызвать эту функцию

2. Может быть, это то, чего я хочу, потому что я действительно не знаю, как это сделать, поэтому я не уверен, правильно ли то, что я думаю, или нет, я попробую ваше, чтобы увидеть, работает это или нет, спасибо, что предоставили мне несколько способов.

3. О, но если я componentDidMount буду использовать внутреннюю функцию, она не будет отображать список тестов в первый раз для меня, поэтому в таблице не будет никаких данных, которые я мог бы отредактировать…

4. Не бери в голову, я тоже это починил! Теперь я счастлива 🙂

5. @Банни, не могли бы вы опубликовать решение в качестве ответа, чтобы другие могли увидеть, как вы его решили?

Ответ №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 amp;amp; (
    <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 = (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`);
                }
            });
    };
 

Это станет обратным вызовом, всякий раз, когда мы нажимаем, например, кнопку редактирования, если она успешно запускается, она обновляется, затем выполняется обратный вызов, и updateQuiz будет запущен в родительском компоненте для повторного запуска, что сразу же отобразит компонент при взаимодействии с дочерним компонентом.