Home > Software engineering >  Empty prop sent to child component and not updated?
Empty prop sent to child component and not updated?

Time:11-23

I am using React and an API in order to fetch data and prefill it to form fields, so that the user can edit an existing record.

However, the child component seems to only be receiving the version of the longhorn entity created in the beginning, instead of the one fetched by the API, also failing to update.

Relevant parent page code:

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

Relevant child component code:

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: ''
        }
    }

If I console.log the longhorn object in the parent, it duplicates the logs several times, showing the empty default set of data in the first three or so, then showing the filled data in the final few logs. Logging the received props in the child shows empty data every time. I've tried creating a new object and destructuring that in the sent props list but it falls victim to the same initial data showing issues.

I suspect it is misusage of the React.UseEffect, but I was having to rely on that to make my async fetch function work properly. Sorry if my code and structure is a bit of a mess, still new to JavaScript

CodePudding user response:

Don't duplicate state.

The child component is making a copy of the very first version it received and then using that version in its own state. Nothing updates this state, so there's no reason for it to change. But why have a separate version in the child state to begin with?

If the data is passed as a prop, use that prop. Remove the state from the child component entirely and just use the prop directly. That way when the parent component re-renders, the child component will use the updated prop value.

CodePudding user response:

You should update your state in the child component when the prop is getting updated because you're only setting your state in child component in the constructor:

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: ''
        }
  }
}
  • Related