DigiPress

Highly Flexible WordPress Theme

メニュー

Material UI (MUI) の DataGrid の autosizeOptions を反映する方法

Material UI (MUI) の DataGrid には autosizeOptions というパラメータが用意されており、これによりカラムの幅を列ヘッダーや行データのサイズを基準にしたり、DataGrid の表示幅に合わせて自動でフィット(拡張)させることができます。

autosizeOptions の指定
<DataGrid
{...otherProps}
autosizeOptions={{
outliersFactor: DEFAULT_GRID_AUTOSIZE_OPTIONS.outliersFactor,
includeOutliers: true, // 行データの幅に合わせる
includeHeaders: false, // 列ヘッダーの幅に合わせる
expand: true, // 表示幅に合わせて自動拡張
}}
/>

しかし、上記のように DataGridautosizeOptions パラメータを設定してもその内容が反映されません。

自動サイズ調整ができない原因

autosizeOptions によるカラム幅の計算は、実際に列ヘッダーや行データが読み込まれて DataGrid がレンダリングされてからでないと正確な算出ができません。
このため、単純に autosizeOptions パラメータをセットしただけでは、DataGrid の非同期の実行によって初期化直後の空のデータグリッドで計算されてしまうために、コンポーネントのレンダリングタイミングとの整合性が取れず、期待通りにカラムが自動調整されない状態になってしまいます。

対処方法

autosizeOptions による自動サイズ調整を反映させるには、ReactDOM.flushSync というメソッドを利用して DOM を強制的に同期的に更新する方法もありますが、React の公式ドキュメントには、「flushSync の使用は一般的ではなく、アプリのパフォーマンスを低下させる可能性がある」とのことなので、setTimeout を利用してデータグリッドのレンダリング完了まで待機してから useGridApiRef によって生成された DataGrid への参照に autosizeColumns を渡すことで指定したオプションにて自動サイズ調整を行います。

setTimeout を利用
// 自動サイズ調整オプション
const autosizeOptions = {
  outliersFactor: DEFAULT_GRID_AUTOSIZE_OPTIONS.outliersFactor,
  includeOutliers: true,
  includeHeaders: true,
  expand: true,
}

const FlexGrid = () => {
  const apiRef = useGridApiRef();
  const [ isLoading, setIsLoading ] = React.useState( true );
  
  React.useEffect(() => {
    const applyAutosize = async () => {
      setIsLoading( true );
      try {
        // データグリッドのレンダリングが完了するまで待機
        await new Promise( ( resolve ) => {
          setTimeout( resolve, 1000 );
        } );
        setIsLoading( false );

        // autosizeColumns を非同期で更新
        await new Promise( ( resolve ) => {
          setTimeout( () => {
            if ( typeof apiRef?.current?.autosizeColumns === 'function' ) {
              apiRef.current.autosizeColumns( autosizeOptions );
            }
            resolve();
          }, 200);
        } );
      } catch ( error ) {
        console.error( "Autosize Error:", error );
        setIsLoading( false );
      }
    };
    applyAutosize();
  }, [ apiRef, autosizeOptions ] );

  return (
    <Box sx={{ height: 400, width: 680, margin: '10px auto' }}>
      <DataGrid
        apiRef={apiRef}
        rows={rows}
        columns={columns}
        loading={isLoading}
        autosizeOptions={autosizeOptions}
      />
    </Box>
  );
}

ReactDOM.createRoot(document.querySelector("#root")).render(<FlexGrid />);

このコードによって、Promise 内で setTimeout によって DataGrid のレンダリングを待ち、apiRef.current.autosizeColumns メソッドが実行可能な状態で autosizeOptions を更新しています。

以下より実際の表示デモで自動サイズ調整がレンダリング後に正しく反映されるのを確認できます。

See the Pen MUI DataGrid Autosizing by digistate (@digistate) on CodePen.

Share / Subscribe
Facebook Likes
Tweets
Hatena Bookmarks
Pinterest
Pocket
Feedly
Send to LINE