Пустой реквизит отправлен дочернему компоненту и не обновлен?

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

Однако дочерний компонент, похоже, получает только версию сущности longhorn, созданную в начале, а не ту, что была получена API, и также не обновляется.

Соответствующий код родительской страницы:

React.useEffect(() => {
        async function getLonghorn() {
            let response = await fetch(`http://127.0.0.1:8081/longhorns/${longhornID}`, { method: 'get' })
            let data = await response.json();
            setLonghorn(await data[0]);
        };

        if (longhorn.Name === "") {
            getLonghorn();
        }

    }, [longhorn.Name, longhornID]);

    return (
        <>
            <Navbar />
            <AdminImageUploadUI type = "longhorn" id = {longhornID} imageList = {imageList}></AdminImageUploadUI>
            <AdminEditLonghornForm {...longhorn} ></AdminEditLonghornForm>
        </>
    )

Соответствующий код дочернего компонента:

import React from 'react'
import { render } from 'react-dom';
import GetRequest from '../../Get';

type props = {
    LonghornID: number, 
    Name: string, 
    RanchPrefix: string, 
    RoleID: number, 
    SexID: number, 
    IsExternal:number, 
    FatherLonghornID:number, 
    MotherLonghornID: number, 
    ReferenceNumber: string, 
    DOB: string, 
    Description:string};

class AdminEditLonghornForm extends React.Component<{}, {
    LonghornID: number, 
    Name: string, 
    RanchPrefix: string, 
    RoleID: number, 
    SexID: number, 
    IsExternal:number, 
    FatherLonghornID:number, 
    MotherLonghornID: number, 
    ReferenceNumber: string, 
    DOB: string, 
    Description:string,
    message: string}> 
    {

    constructor(props: props) {
        super(props)

        this.state = {
            LonghornID: props.LonghornID,
            Name: props.Name,
            RanchPrefix: props.RanchPrefix,
            RoleID: props.RoleID,
            SexID: props.SexID,
            IsExternal: props.IsExternal,
            FatherLonghornID: props.FatherLonghornID,
            MotherLonghornID: props.MotherLonghornID,
            ReferenceNumber: props.ReferenceNumber,
            DOB: props.DOB,
            Description: props.Description,
            message: ''
        }
    }

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

Я подозреваю, что это неправильное использование React.UseEffect, но мне приходилось полагаться на это, чтобы моя функция асинхронной выборки работала правильно. Извините, если мой код и структура немного беспорядочны, все еще новичок в JavaScript

await data[0] ? Почему у тебя там await?
David 22.11.2022 20:58

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

8times9 22.11.2022 21:15
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
2
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы должны обновить свое состояние в дочернем компоненте, когда обновляется реквизит, потому что вы устанавливаете свое состояние только в дочернем компоненте в конструкторе:

componentDidUpdate(prevProps) {
  if (JSON.stringify(prevProps) !== JSON.stringify(this.props)) {
    this.state = {
            LonghornID: this.props.LonghornID,
            Name: this.props.Name,
            RanchPrefix: this.props.RanchPrefix,
            RoleID: this.props.RoleID,
            SexID: this.props.SexID,
            IsExternal: this.props.IsExternal,
            FatherLonghornID: this.props.FatherLonghornID,
            MotherLonghornID: this.props.MotherLonghornID,
            ReferenceNumber: this.props.ReferenceNumber,
            DOB: this.props.DOB,
            Description: this.props.Description,
            message: ''
        }
  }
}

Еще лучше не дублировать одно и то же состояние в нескольких компонентах.

David 22.11.2022 21:02

Ну да, это хорошее улучшение. Спасибо.

Amirhossein 22.11.2022 21:04
Ответ принят как подходящий

Не дублируйте состояние.

Дочерний компонент делает копию самой первой полученной версии, а затем использует эту версию в своем собственном состоянии. Ничто не обновляет это состояние, поэтому нет причин для его изменения. Но зачем для начала иметь отдельную версию в дочернем состоянии?

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

Спасибо за ответ. Я пытаюсь сделать значения ссылок на реквизиты форм напрямую, как вы упомянули, набрав this.props.XXX, но получаю сообщение об ошибке Property 'XXX' does not exist on type 'Readonly<{}>'? Я столкнулся с этим ранее и исправил его, добавив реквизиты и их типы в определение React.Component, но, учитывая, что они все еще присутствуют, я не уверен, почему он все еще ведет себя таким образом.

8times9 22.11.2022 21:11

@ 8times9: я не на 100% знаком с синтаксисом TypeScript для компонентов класса React, но эта ошибка означает, что мне может потребоваться изменить спецификатор типа для самого компонента. Обратите внимание, что при расширении React.Component<> вы включаете два определения типа, и первое — это пустой объект. Что, если вы вместо этого используете свой тип props?

David 22.11.2022 21:17

Браво! Исправлена ​​проблема, и теперь данные заполняются в поля формы должным образом.

8times9 22.11.2022 21:25

Другие вопросы по теме