0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Reactのコンポーネントを、Vueのコンポーネントみたいに利用したい!

Posted at

React は class の上書きや slot が無いせいで、ちょっと使いにくいところが多い。

試行錯誤した結果、以下がテンプレになると思われる。

import clsx from 'clsx'

export function MyComponent(
  { args, children, ...props }:
  & React.PropsWithChildren<{ args: string }>
  & React.HTMLAttributes<HTMLElement>
) {
  return (
    <div
      className={clsx(
        '<component class>',
        props.className, // override
      )}
      {...props} // override
    >
      {children}
    </div>
  )
}

引数要素: args

このコンポーネントに渡したい値は args で渡す。
argsobject でも、複数あっても良い。
渡す値を React.PropsWithChildren に型定義してあげる。

ここの型が defineProps と同義である。

スロット要素: children

このコンポーネントに渡す slot 要素は、ここに入ってくる。
基本的に default スロットしかなく、named slot を使うにはコツが必要。

この children は単体か配列かは不定なので、mapfilter のかけ方は下を参照。
Children.toArray(children) をする必要がある。
https://ja.react.dev/reference/react/Children

HTML属性: props

最後に純粋にHTML属性を反映させるのが props
props は、分割代入の余り、つまり argschildren 以外のものが格納されている。

ここに React.HTMLAttributes で型情報を与えてあげることで、HTML属性を親から反映させることが可能となる。
<HTMLElement> は Root の要素に応じて変えてあげよう。

ただ、className に関してはコンポーネントで定義したものと、親で定義したものが競合するので、clsx でちゃんとハンドリングしてあげたほうが良い。


こんな感じで、親から override できるように運用するのがよさそう。
この辺の型運用が、公式ドキュメントに載ってないのなんで...?
私が見つけられてないだけ...?

0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?