NativeBase ちょっと複雑な Accordion

TypeScript で NativeBaseAccordion を実装する際のメモです。

基本ケース

dataArray プロパティに渡したデータを表示をしてくれます。 title が見出し表示、content が内容表示(具体的には Text タグによってシンプルに表示)がデフォルト挙動です。

import React from 'react';
import { Accordion } from 'native-base';

export function Accordion1() {
  const dataArray = [
    { title: 'Title1', content: 'Content1' },
    { title: 'Title2', content: 'Content2' },
  ];
  return (<Accordion dataArray={dataArray} />);
}

データ構造に一貫性がないケース

内容表示をカスタマイズしたい場合は、renderContent プロパティを使えば良いわけですが、さらに、dataArray データ構造が各要素毎に異なる場合のアプローチを考えました。title というデータ内で一意になるであろうキーが存在するので、それを元に Union 型を判別しちゃえば良いのかなーと。

import React from 'react';
import {
  Accordion, Text,
} from 'native-base';

type AccordionData = {
  title: 'Title1'
  content: string
} | {
  title: 'Title2'
  content1: string
  content2: string
}

function renderContent(data: AccordionData) {
  switch (data.title) {
    case 'Title1':
      return (<Text>{data.content}</Text>);
    case 'Title2': {
      const dataArray = [
        { title: 'Title2-1', content: data.content1 },
        { title: 'Title2-2', content: data.content2 },
      ];
      return (<Accordion dataArray={dataArray} />);
    }
    default:
      throw new Error();
  }
}

export function Accordion2() {
  const dataArray: AccordionData[] = [
    { title: 'Title1', content: 'Content' },
    { title: 'Title2', content1: 'Content1', content2: 'Content2' },
  ];
  return (
    <Accordion
      dataArray={dataArray}
      renderContent={renderContent}
    />
  );
}

上記サンプルコードは、ついでに Accordion をネストさせてみました。

要素数よりもデータ構造パターン数が少ない場合(title で一意にデータ構造が決まらない場合)や、title の内容が動的で事前に判断がつかない場合などは title ではなく、別のキーを使えば良いですね。