20190126のReactに関する記事は2件です。

Reatに入門して1日目の私がつまずいた用語

DOM

Document Object Modelの略
HTMLやXMLの各要素にアクセスする仕組みのこと。

JSX

JavaScriptを拡張した言語
Reactを用いて、HTMLを出力するもの。
見た目は、HTMLと似ている。
JSXはアプリケーション内部では、トランスパイルされJavaScriptのコードに変更される。
JSXをJavaScriptにトランスパイルしているのはBabel

トランスパイルとは

ある言語で書かれたコードをもとに、別の言語のコードに書き換えること。

なぜJSXを使うのか?

JavaScriptを書くよりも、可読性が高く書きやすい為。

JSXとJavaScriptでHello, World

sample.js
// JSXの場合
render() {
  return <div>Hello, World</div>;
}

//JavaScriptの場合
render() {
  return React.returnElement(
    "div",
    nul,
    "Hello, World"
  );
}

JSXの方が書きやすいのは明白。

Webpack

複数のファイルを1つにまとめて、Webに読み込みやすくするもの。

Component

Webサイトを構成する部品のこと。
Reactには2つにComponentがある。
componentは再利用することができる。

functional component

関数の定義によって作成するコンポーネント

class component

クラスの定義によって作成するコンポーネント

props

componentの属性
propsには文字列や関数などなんでも使うことができる。
基本的には{}に囲って属性を渡す。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

雰囲気で使わない @types/react

@types/react の型定義を雰囲気で使っている皆さん、こんにちは。React コンポーネントを書くときはどの型を使い、どう書くべきか?という疑問を Twitter でお見かけし、雰囲気で使っていた私も気になったので @types/react の中身を覗いてみました。

master に入り、いよいよリリース間近な Hooks。本稿は FC(旧SFC) の話が前提です。VScode で型付けをしようとすると、似たような型が山ほど出てきて、どれを使うのが適切なのか・違いが何なのか…パッと見分かりませんね。

  • ReactNode
  • ReactChild
  • ReactElement
  • StatelessComponent
  • FunctionComponent
  • JSX.Element
  • SFC
  • FC

という訳で、こんな Props を持っているコンポーネントの各種書き方を比較、白黒ハッキリさせていきたいと思います。

type Props = { test: 'test' }

? Winners

結論からいうと、以下二つのどちらかの書き方が良さそうです。

const MyComponentA: React.FunctionComponent<Props> = props => (<></>)
const MyComponentB: React.FC<Props> = props => (<></>)

引数の props に型注釈を入れていませんが、これだけで推論はちゃんと動いてくれます。定義元の React.FunctionComponentprops: P & { children?: ReactNode }が既に入っているので、プログラマー定義のP型 type Props = { test: 'test' } とマージしてくれます。これが勝者たる所以です。React.FC は React.FunctionComponent の定義を参照しているため、全く同じものと言えます。

type FC<P = {}> = FunctionComponent<P>;

React.FunctionComponent が本流ですが、長ったらしいので、React.FC のほうが自分は好みです。つぎに、残念ながら良くなさそうな書き方を紹介します。

?‍♀️ children? を自前で入れる必要アリ

基本的に推論に頼りたい派なので、今まで自分はこの書き方をしていました。render children が必要な度、type Propschildren?: ReactNode を自前で注入しなければならず、やや冗長です。

const MyComponentC = (props: Props) => (<></>)
const MyComponentD = (props: Props): JSX.Element => (<></>)
const MyComponentE = (props: Props): React.ReactElement<any> => (<></>)

MyComponentCの戻り型推論はJSX.Elementで、JSX は @types/react の中で切られている namespace です。JSX.Element は、React.ReactElement を空継承しています。つまり、この3つの書き方は全く同じであり、後者二つは戻り型注釈付与の意味がない事になります。

interface Element extends React.ReactElement<any> { }

?‍♂️ 型が緩い

特に困ることはないですが、React.ReactElement を含んだ UnionTypes なので次の書き方でもコンパイルは通ります。ReactNode や ReactChild には、FunctionComponent 以外にも色んな型が UnionTypes で入っており、コンポーネント以外の型へも、制限を緩めてしまっています。ReactText の実体は string | number です。

// type ReactChild = ReactElement<any> | ReactText;
const MyComponentF = (props: Props): React.ReactChild => (<></>)

// type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
const MyComponentG = (props: Props): React.ReactNode => (<></>)

こんなコンポーネントを作る人はいないでしょうが、コンパイルエラーを得られていないことから、間違っていることは明らかです。

const MyComponentF = (props: Props): React.ReactChild => (0)
const MyComponentG = (props: Props): React.ReactNode => (null)

? そもそも deprecated

@deprecated as of recent React versions, function components can no longer be considered 'stateless'. Please use FunctionComponent instead. @see React Hooks

だそうです。Hooks の影響をもろに受けている…。この書き方をしていたら、気分が向いた時に書き換えましょう。

const MyComponentH: React.StatelessComponent<Props> = props => (<></>)
const MyComponentI: React.SFC<Props> = props => (<></>)

ちなみに、この二つどちらもReact.FCと同様に、React.FunctionComponentのエイリアスでしかないので、定義内容は一緒です。似たような定義山ほどあった理由は、前方互換を担保したりショートハンドを提供するためだった、というお話でした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む