ReactのためのJavaScript, TypeScript

27327 ワード

Introduction

※本稿は Vue.js しか触ったことがない筆者が React.js , TypeScript を記述する上で必要な知識をメモしたものになります

JavaScript を学びたての人がいきなり React.js を TypeScript で書こうとするのは中々難しいのではないかと思います。
ということで、本稿では Vue.js で必要な JavaScript しか書いてこなかった私が React.js を TypeScript で書くために必要最低限な知識をまとめています。

JavaScript for React

conditional

conditional というのは条件分岐のことで、JavaScript では以下のように書けます。
また、単純な if, else 文の場合三項演算子を使ってやや省略して記述することも可能です。

const condition = true;

if (condition === true) {
  console.log('condition is true');
} else {
  console.log('condition is false');
}
// condition is true

// 三項演算子
condition === true ? console.log('condition is true') : console.log('condition is false');

React では以下のようにレンダリングさせたい JSX を条件によって分岐させたい場合等に使われます。

const Test = () => {
  const condition = true;

  if (condition) {
    return <h3>condition is true</h3>;
  } else {
    return <h3>condition is false</h3>;
  }
};

これは三項演算子を使って以下のように書くこともできます。

const Test = () => {
  const condition = true;

  const isTrue = condition ? <h3>condition is true</h3> : <h3>condition is false</h3>;

  return isTrue;
};

loop

React で loop を記述する時は map() を使います。
まず, JavaScript では以下のように iterable な変数に対して map() を使用します。

const arr = ['a', 'b', 'c'];
arr.map((e) => console.log(e));
// a
// b
// c

React では以下のように繰り返しでレンダリングする場合等に使用します。

const Test = () => {
  const arr = ['a', 'b', 'c'];

  return (
    <div>
      {arr.map((e, i) => <h3 key={i}>element is {e}</h3>)}
    </div>
  )
};

destrucuture, spread operator

ES6 から JavaScript では配列とオブジェクトについてdestrucuture記法で分割代入が可能になりました。
以下のように宣言・代入済みの配列・オブジェクトから新たに変数を代入することができます。

const arr = ['apple', 'banana', 'cookie'];
const [item1, item2, item3] = arr;
// item1 = 'apple', item2 = 'banana', item3 = 'cookie'

const obj = {
  id: 1,
  name: 'miyuki',
};
const {id, name} = obj;
// id = 1, name = 'miyuki'

また、ES6からspread operator(...)で以下のように分割代入をすることも可能です。

const arr = [1,2,3];
const newArr = [...arr,4,5] // [1,2,3,4,5]

const obj = {
  id: 1,
  name: 'miyuki',
};
const newObj = {
  ...obj,
  job: 'engineer',
} // { id: 1, name: 'miyuki', job: 'engineer' }

React では useState() を筆頭にした Hooks を利用する時によく使います。
以下は shopCart というオブジェクト型の state に対して、値を追加するような例です。
state の代入時とオブジェクトに対する値の追加時に destrucuture や spread operator を使っています。

const Test = () => {
  const [shopCart, setCart] = useState({item1: 'apple'});
  const addCart = () => {
    return (
      setCart((prevState) => ({
        ...prevState,
        item2: `banana`,
      }))
  )};

  return (
    <div>
      <h1>useState shopCart demo</h1>

      <button onClick={addCart}>setCart</button>
      <br></br>
      <label>Output:</label>
      <pre>{JSON.stringify(shopCart, null, 2)}</pre>

    </div>
  )
};

TypeScript for React

interface

interface とは, TypeScript で静的に型付けするオブジェクトです。オブジェクト型の型指定をするときに使います。

interface Obj {
  id: number,
  name: string,
}

const obj: Obj = {
  id: 1,
  name: 'miyuki',
}

React では関数コンポーネントに渡す props がオブジェクト型になるので, props に適用することができます。

interface AppProps {
  id: number,
  name: string,
}

const Child = (props: AppProps) => {
  return (
    <div>
      <p>id is {props.id}</p>
      <p>name is {props.name}</p>
    </div>
  )
};

const Test = () => {
  return (
    <div>
      <Child id={1} name='miyuki' />
    </div>
  )
};

generics

generics とは変数や関数において、宣言時ではなく代入時に型付けする方法です。

function Foo<T>(arg: T): T {
  return arg;
}

const foo = Foo<string>('foo');

React では useState() のような React の組み込み関数を使用する際に使います。
以下では useState() で初期化する state の型を指定しています。

const TestState = () => {
  const [cnt, setCnt] = useState<number>(0);
  const incr = () => setCnt(cnt + 1);

  return (
    <div>
      <button onClick={incr}>incr</button>
      <p>{cnt}</p>
    </div>
  )
};

Reference

  1. JavaScript Primer
  2. React Docs
  3. TypeScript Docs