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
相关产品推荐
相关产品推荐

