はじめに
こんにちは、エンジニアのkeitaMaxです。
上記の記事を参考に自分のリポジトリにもWhenとMatchを実装して使ってみました。
実装
記事で紹介されていたWhenとMatchを型を指定して以下のように書いてみました。
MatchWhen/index.tsx
import React from 'react'
type MatchProps = {
children: React.ReactNode;
}
export const Match = React.memo<MatchProps>(function Match({
children
}) {
return (
React.Children.toArray(children).find(
(child) =>
React.isValidElement(child) &&
((child.props.exp || child.props.otherwise) as boolean)
) || <></>
)
})
type WhenProps = {
children: React.ReactNode;
exp?: boolean | number;
otherwise?: boolean;
}
export const When = React.memo<WhenProps>(function When({
children,
exp = false,
otherwise = false
}) {
return exp === 0 ? <></> : (exp || otherwise) ? <>{children}</> : <></>
})
直してみるコード
以下のコードをWhenとMatchで書き換えてみようと思います。
import React, { useState } from 'react'
export const OldMatchView = React.memo(function OldMatchView() {
const [selectedValue, setSelectedValue] = useState(1)
return (
<>
<div className="mb-4 flex space-x-4">
{[1, 2, 3].map((value) => (
<label key={value} className="flex items-center space-x-2">
<input
type="checkbox"
checked={selectedValue === value}
onChange={() => setSelectedValue(value)}
className="cursor-pointer"
/>
<span>{value}</span>
</label>
))}
</div>
{selectedValue === 1 && (
<div>Content for 1</div>
)}
{selectedValue === 2 && (
<div>Content for 2</div>
)}
{selectedValue === 3 && (
<div>Content for 3</div>
)}
{![1, 2, 3].includes(selectedValue) && (
<div>No data available</div>
)}
</>
)
})
export default OldMatchView
直したコード
以下のように直してみました。
確かにこっちの方が見やすくてコードがシンプルになる気がします。
import React, { useState } from 'react'
import { Match, When } from '~/components/MatchWhen'
export const MatchView = React.memo(function MatchView() {
const [selectedValue, setSelectedValue] = useState(1)
return (
<>
<div className="mb-4 flex space-x-4">
{[1, 2, 3].map((value) => (
<label key={value} className="flex items-center space-x-2">
<input
type="checkbox"
checked={selectedValue === value}
onChange={() => setSelectedValue(value)}
className="cursor-pointer"
/>
<span>{value}</span>
</label>
))}
</div>
<Match>
<When exp={selectedValue === 1}>
<div>Content for 1</div>
</When>
<When exp={selectedValue === 2}>
<div>Content for 2</div>
</When>
<When exp={selectedValue === 3}>
<div>Content for 3</div>
</When>
<When otherwise>
<div>No data available</div>
</When>
</Match>
</>
)
})
export default MatchView
おわりに
この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。
最後まで読んでいただきありがとうございました!
参考