You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React子组件接收空Props且无法更新问题求助

问题分析与解决

核心问题

  1. 子组件state未随props更新:你的子组件是类组件,constructor只会在组件挂载时执行一次,把初始props同步到state。当父组件通过API获取到数据更新longhorn后,子组件的props虽然变化,但state不会自动更新,所以始终显示初始空数据。
  2. 父组件useEffect依赖与触发逻辑有问题:依赖longhorn.Name会导致每次Name变化都触发请求,而且初始判断longhorn.Name === ""可能在数据更新后再次触发不必要的请求。

解决步骤

1. 修复子组件的state更新逻辑

首先纠正类组件的泛型参数(你之前把props类型设成了空对象,导致props无法被正确识别),然后添加componentDidUpdate生命周期方法,监听props变化并同步更新state:

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};

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

// 修正泛型参数:第一个是Props类型,第二个是State类型
class AdminEditLonghornForm extends React.Component<Props, State> {
    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: ''
        }
    }

    // 添加这个方法,当props变化时更新state
    componentDidUpdate(prevProps: Props) {
        // 对比关键props,避免不必要的state更新
        if (prevProps.LonghornID !== this.props.LonghornID || prevProps.Name !== this.props.Name) {
            this.setState({
                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,
            })
        }
    }

    // 剩下的组件代码...
}

2. 优化父组件的useEffect逻辑

去掉longhorn.Name作为依赖项,改用longhornID和初始状态判断,避免重复请求:

// 假设你的longhorn初始状态是这样的:
const [longhorn, setLonghorn] = React.useState<Props>({
    LonghornID: 0,
    Name: "",
    RanchPrefix: "",
    RoleID: 0,
    SexID: 0,
    IsExternal: 0,
    FatherLonghornID: 0,
    MotherLonghornID: 0,
    ReferenceNumber: "",
    DOB: "",
    Description: ""
})

React.useEffect(() => {
    async function getLonghorn() {
        try {
            let response = await fetch(`http://127.0.0.1:8081/longhorns/${longhornID}`, { method: 'get' })
            let data = await response.json();
            // 确保data[0]存在再设置
            if (data[0]) {
                setLonghorn(data[0]);
            }
        } catch (err) {
            console.error('获取数据失败:', err)
        }
    };

    // 只有当longhornID有效,且当前longhorn是初始状态时才请求
    if (longhornID && longhorn.Name === "") {
        getLonghorn();
    }

}, [longhornID]); // 只依赖longhornID,避免重复触发

return (
    <>
        <Navbar />
        <AdminImageUploadUI type="longhorn" id={longhornID} imageList={imageList}></AdminImageUploadUI>
        {/* 可以加个判断,数据没加载完时显示加载状态,避免子组件接收空数据 */}
        {longhorn.Name ? <AdminEditLonghornForm {...longhorn} ></AdminEditLonghornForm> : <div>加载中...</div>}
    </>
)

额外建议

  • 可以给父组件加个isLoading状态,更清晰地控制加载过程,比如:
    const [isLoading, setIsLoading] = React.useState(false);
    // 在getLonghorn里设置setIsLoading(true),请求完成后setIsLoading(false)
    
  • 如果熟悉函数组件,把子组件改成函数组件会更简洁,用useEffect监听props变化更新state,或者直接用props控制表单(推荐,避免state和props不同步)。

内容的提问来源于stack exchange,提问作者8times9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 11:55:20