You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ag-Grid下拉列修改值后自动恢复初始状态的问题求助

Ag-Grid下拉列修改值后自动恢复初始状态的问题求助

你好!我看了你的代码,问题的核心原因是Ag-Grid不会自动修改你通过useState维护的rowData状态。当你在下拉框里选择新值后,Ag-Grid虽然拿到了编辑器返回的新值,但没有同步到你的数据源rowData中,所以一旦失去焦点,表格会重新从原始的rowData读取旧值,导致看起来像是“恢复到初始状态”。

下面是具体的解决步骤和修改后的完整代码:

解决步骤

  1. 添加单元格值变更回调,同步更新rowData
    AgGridReact组件加上onCellValueChanged事件处理函数,在编辑完成后手动更新对应的行数据,让你的rowData状态和表格的单元格值保持一致。

  2. 完善自定义编辑器的状态同步(可选但推荐)
    给自定义编辑器添加useEffect监听props.value的变化,确保编辑器初始化时能正确获取最新的单元格值,避免编辑器状态和单元格值不一致的情况。

修改后的完整代码

import React, { useState, useCallback, forwardRef, useImperativeHandle, useEffect } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
import { ICellEditorComp } from 'ag-grid-community';

interface DropdownEditorProps {
  value: string;
  values: string[];
}

const DropdownEditor = forwardRef<ICellEditorComp, DropdownEditorProps>(
  (props, ref) => {
    const [selectedValue, setSelectedValue] = useState(props.value);

    // 监听外部值变化,同步编辑器选中状态
    useEffect(() => {
      setSelectedValue(props.value);
    }, [props.value]);

    useImperativeHandle(ref, () => {
      return {
        getValue() {
          return selectedValue;
        },
        isPopup() {
          return true;
        },
        // 可选:编辑器初始化后自动获取焦点,提升体验
        afterGuiAttached() {
          const selectEl = document.querySelector('select');
          selectEl?.focus();
        }
      };
    });

    const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
      setSelectedValue(event.target.value);
    };

    return (
      <select value={selectedValue} onChange={handleChange} style={{ width: '100%' }} >
        {props.values.map((option) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </select>
    );
  }
);

const testapp: React.FC = () => {
  const [rowData, setRowData] = useState([
    { Color: 'Green', make: 'Tesla', model: 'Model Y', price: 64950 },
    { Color: 'Blue', make: 'Ford', model: 'F-Series', price: 33850 },
    { Color: '', make: 'BMW', model: 'BMW Series', price: 5000 },
  ]);

  const [colDefs] = useState([
    {
      field: 'Color',
      editable: true,
      cellEditor: DropdownEditor,
      cellEditorParams: {
        values: ['Normal', 'Green', 'Red', 'Blue'],
      },
    },
    { field: 'make' },
    { field: 'model' },
    { field: 'price' },
  ]);

  // 处理单元格值变更,同步到rowData状态
  const handleCellValueChanged = useCallback((params: any) => {
    setRowData(prevRows => {
      return prevRows.map(row => {
        // 定位到被修改的行,更新对应字段
        if (row === params.data) {
          return { ...row, [params.colDef.field]: params.newValue };
        }
        return row;
      });
    });
  }, []);

  return (
    <div className="ag-theme-alpine" style={{ width: 800, height: 400 }}>
      <AgGridReact
        rowData={rowData}
        columnDefs={colDefs}
        singleClickEdit={true}
        // 新增单元格值变更回调
        onCellValueChanged={handleCellValueChanged}
        gridOptions={{
          stopEditingWhenCellsLoseFocus: true,
          rowSelection: { mode: 'singleRow', checkboxes: false },
        }}
      />
    </div>
  );
};

export default testapp;

关键修改点说明

  • onCellValueChanged回调:这是解决问题的核心,它在编辑完成后将新值同步到你的rowData状态中,确保表格下次渲染时使用更新后的数据源。
  • 编辑器中的useEffect:监听props.value的变化,避免当重新编辑同一行时,编辑器仍显示旧值的问题。
  • 补充afterGuiAttached方法:可选操作,让编辑器初始化后自动获取焦点,优化编辑的流畅度。

这样修改后,你修改下拉框的值并失去焦点后,表格就会保持你选择的新值,不会再自动恢复到初始状态了。

内容来源于stack exchange

火山引擎 最新活动