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

AdminJS资源自定义edit组件提交时无法同步更新字段值

AdminJS自定义编辑组件值更新后提交Payload未同步问题

问题现象

为service_subcategory资源的parent_service_id字段(与servicecategory模型为belongsTo关联关系)配置基于react-select实现的自定义编辑组件时,选择新选项后控制台打印可确认组件内部state已正确更新,但表单提交时请求payload中parent_service_id仍为初始原始值,其余使用AdminJS默认组件的字段均可正常提交更新后的值。

复现代码

Sequelize模型与资源配置

const ServiceSubCategory = db.sequelize.define("service_sub_categories", {
  name_en: {
    type: db.Sequelize.STRING,
    allowNull: false,
  },
  name_cn: {
    type: db.Sequelize.STRING,
    allowNull: false,
  },
  name_zh: {
    type: db.Sequelize.STRING,
    allowNull: false,
  },
  parent_service_id: {
    type: db.Sequelize.INTEGER,
    allowNull: false,
  },
  parent_service_new_id: {
    type: db.Sequelize.VIRTUAL,
    allowNull: true,
  },

});
const options = {
  properties: {
   
    parent_service_id: {
      components: {
        list: AdminJS.bundle('./../../components/admin/service_sub_categories/list_service_category_id_field.jsx'),
        show: AdminJS.bundle('./../../components/admin/service_sub_categories/show_service_category_id_field.jsx'),
        edit: AdminJS.bundle('./../../components/admin/service_sub_categories/edit_service_category_id_field.jsx')
      },
    },
  },
};
module.exports = {
  options,
  resource: ServiceSubCategory,
};

自定义react-select编辑组件

import React, {Component} from 'react'
import Select from 'react-select'
import {FormGroup, FormMessage} from "@adminjs/design-system";
import { Label } from '@adminjs/design-system'
class SelectParentServiceID extends Component {


    state = {
        selectedOption: {
            value: this.props.record.populated.parent_service_id.params.id,
            label: this.props.record.populated.parent_service_id.params.name_en,
        },
        value: this.props.record.populated.parent_service_id.params.id,
        parent_service_id: this.props.record.populated.parent_service_id.params.id,
    };

    handleChange = (selectedOption) => {
        this.setState({ 
            selectedOption: selectedOption, 
            value: selectedOption.value, 
            parent_service_id: selectedOption.value
        }, () => {
                console.log(`Option selected:`, this.state.selectedOption)
                console.log(`Option selected:`, this.state.parent_service_id)
        });
    };


    componentDidMount() {
        this.fetchData()
    }

    fetchData = async () => {
        let data;
        try {
            const response = await fetch('/api/servicecategories/get/');
            data = await response.json();
            const options = data.map(d => ({
                "value" : d.id,
                "label" : d.name_en
            }))
            this.setState({selectOptions: options})
        } catch (error) {
            console.log('error', error);
        }
    }

    render() {
        return (
            <FormGroup error={''}>
                <Label htmlFor={'parent_service_id'} required={true}>Parent Service Category</Label>
                <Select options={this.state.selectOptions}
                        onChange={this.handleChange}
                        defaultValue={this.state.selectedOption}
                        required={true}
                        name={'parent_service_id'}
                        value={this.state.selectedOption}
                />
                <FormMessage>{''}</FormMessage>
            </FormGroup>
        )
    }
}

export default SelectParentServiceID

现象截图

问题原因

AdminJS的自定义编辑组件不会自动同步组件内部state到外层表单全局状态,仅维护组件内部state时,外层表单无法感知字段值变化,提交时会始终读取记录初始加载的旧值。

修复方案

选项变更时,调用组件props传入的onChange方法,将更新后的值同步到AdminJS表单记录中,仅需修改handleChange方法即可:

handleChange = (selectedOption) => {
    const newValue = selectedOption.value;
    this.setState({ 
        selectedOption: selectedOption, 
        value: newValue, 
        parent_service_id: newValue
    }, () => {
        // 同步字段值到AdminJS外层表单状态
        this.props.onChange(
            this.props.property.name,
            Number(newValue) // 保证值类型与数据库字段类型一致,为整数ID
        );
        console.log(`Option selected:`, this.state.selectedOption)
        console.log(`Option selected:`, this.state.parent_service_id)
    });
};

额外注意:组件初始化取值时优先从this.props.record.params.parent_service_id读取当前字段实际值,populated仅为关联数据的展示用数据,字段值变更后不会自动更新,避免出现值和展示文本不匹配的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:42:26