[antd] TableのColumnやColumnGroupは（現在）ただの印である

この記事は2022年1月現在なので、将来変わるかもしれません

# Tableの`Column`や`ColumnGroup`

Ant DesignのTableを使う際に、`Column`や`ColumnGroup`を使いますが、

[Table - Ant Design](https://ant.design/components/table/#components-table-demo-jsx)

> Since this is just a syntax sugar for the prop `columns`, you can't compose `Column` and `ColumnGroup` with other Components.
> 

jsxで記述する `Column` や `ColumnGroup`はわかりやすさのために中身がない糖衣構文的なコンポーネントである。

つまり、ただの印であり実装上の意味を持ちません。

（そもそも昔はjsxで記述するものではなくオブジェクトで記述するものだったため？）



実装
[https://github.com/ant-design/ant-design/blob/master/components/table/Column.tsx](https://github.com/ant-design/ant-design/blob/master/components/table/Column.tsx)

例えば公式サンプルのこの例

[https://codesandbox.io/s/yqy7e](https://codesandbox.io/s/yqy7e)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15024/b9ecf799-d0c7-b81e-07e4-f65cd9fa87e3.png)

ですが、

すべて `div` タグに書き換えても同じように動きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15024/7d2b330c-418b-e7c6-36db-2e7a310e19e6.png)

# 理由

Ant Designというより、さらに依存している react-component/table の仕様にはなるのですが、

[https://github.com/react-component/table/blob/master/src/hooks/useColumns.tsx#L22](https://github.com/react-component/table/blob/master/src/hooks/useColumns.tsx#L22)

ここの部分で key と props だけ取り出していることがわかります。

コンポーネント名を活かすなら**type**なども活用されるはずです。

つまり、jsxのpropsやchildren（子要素）があるかどうかだけに影響されるのです。

# できないこと

別にそういうこともあるよねくらいの気持ちでも良いのですが、

これでできないことは列に対するカスタムコンポーネントが作れなくなります。

実用上だと列を動的に生成したいなどでこのようにすることもあると思います。

```csharp
export const CustomColomn = () => {
  return <Column title="Age" dataIndex="age" key="age" />
}
```

のように作ってjsxで使っても、 何も表示されなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15024/ced74aa5-da8c-108b-8c59-b49cd00cd3fa.png)


忘れやすいですがカスタムコンポーネントは、処理の分離だけできるというわけでなく

実装上は もちろん `CustomColomn` というコンポーネントを1段階挟んでいて propsなどは空になっているのです。

ちなみに、

```tsx
<Table dataSource={data}>
    {CustomColomn()}
</Table>,
```

のように関数呼び出しにすれば大丈夫ではありますが、これが良いかどうかは..皆さんのご判断で

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15024/9374b1a9-630e-49f3-8f00-932b021b8ae2.png)

propsも設定すると大丈夫にはなりますが、
カスタムコンポーネントを使って分離する意義が少し薄れます。

```tsx
<Table dataSource={data}>
    <CustomColumn title="Age" dataIndex="age" key="age"  />
</Table>,
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15024/918f7a76-3d87-f9ad-7184-80da9e32bf8f.png)



mapを使って動的に列の数も増やすという場合


こういうコンポーネントを使っても何も出ないということになります。


```tsx
export const CustomColomns = () => {
  return [1, 2, 3].map((v) => <Column title={"param" + v} />);
};
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15024/5d70b681-1417-4d2f-225f-290f32113445.png)

なので動的に列を増やしたいときは Table直下にコンポーネントを経由せずにmapを書かないといけないと思います。


```tsx
<Table dataSource={data}>
    {[1, 2, 3].map((v) => (
      <Column title={"param" + v} />
    ))}
</Table>,
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15024/dd2e4ffe-ee51-00cb-3e31-50c65493cbdd.png)


# まとめ

`Column`や `ColumnGroup`は、実装上は意味を持たないものである。
ですが、将来仕様が変わるかもしれないのでもちろんこれらを使うべきである。

処理の分離するときにカスタムコンポーネントをよく使うが、1段挟まれるので、
等価ではなく意図しない挙動になるかもしれないという考慮には入れておく。
（おそらく大抵は大丈夫だと思うが）
このコンポーネント以外にもこういうのはあるかもしれないです。