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?

More than 3 years have passed since last update.

制御コンポーネントの作成

Last updated at Posted at 2021-05-28

Inputフィールドの作成

コンポーネントを一通り学んだ後に簡単なInputフィールドを作って遊んでみました。
しかし、意外と簡単にはいかず、良い復習になったので備忘録を残しておきます。

簡単な書き方

こんな感じで書いてみました。
ブラウザから見るととりあえず動いています。

import React, { useState, useCallback, useMemo } from 'react';
import './App.css';

const App=()=> {
  return (
    <div className="App">
      <header className="App-header">
        <input type="text"/>
      </header>
    </div>
  );
}

export default App;

この場合、コンポーネントの状態 (state) を全く記述しておらず、入力の状態をどう保持するのかって感じです。
*このようなコンポーネントを「ステートレスコンポーネント (stateless component)」と言うそうです。
また、値の状態がビューと切り離されておらず、アプリケーションの設計としては良いとは言えないです。

stateの管理

Inputの値(value)をstateで管理します。

const App=()=> {
  const [message, setMessage] = useState('');
  return (
    <div className="App">
      <header className="App-header">
        <input type="text" value={message}/>
      </header>
    </div>
  );
}

const [message, setMessage] = useState('')stateを保持します。

  • message .. state変数
  • setMessage .. state変数の状態を変更するための関数

クラスコンポーネントはthis.stateと言う書き方で内部の値を保持することができましたが、関数コンポーネントでは同様の書き方はできません。そこで、HookのuseStateを使ってあげて変数の状態を保持することを可能とします。

参考)useState を呼ぶと何が起きるの?

これにより『state 変数』が宣言されます。useState は、クラスにおいて this.state が提供するのと全く同じ機能を実現するための新しい方法です。通常、関数が終了すると変数は『消えて』しまいますが、state 変数は React によって保持されます。

これで再度ブラウザから動きを確認します。。。
何も入力できないことが分かります。

stateの変更

ここで公式ドキュメントのuseStateを再度確認します。
useStateは「state変数とstate変数の状態を変更するための関数」を返します。
2つ目の戻り値と言うのが「state変数の状態を変更するための関数」であり、言い換えると「state変数の状態を変更したい場合はこの関数を呼ぶ」と言うことです。これをしっかりと理解していないと上のようなことが起きてしまいます。

カウントダウンのような機能の場合、関数コンポーネント内に以下のように書きます。

const [count, setCount] = useState(0);

<button onClick={() => setCount(count + 1)}>

messageの状態を変更するための関数setMessageを定義を呼び出すための関数(ハンドラ)を定義し、inputフィールドのonChanged属性に指定します。

const App=()=> {
  const [message, setMessage] = useState('');
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setMessage(e.target.value);
  };
  return (
    <div className="App">
      <header className="App-header">
        <input type="text" value={message} onChange={handleChange} />
      </header>
    </div>
  );
}

これでやりたいことは実現できます。

このようなにコンポーネントの内容をstateの状態で保持するものを制御コンポーネントと言うみたいです。

コンポーネントの分割

おまけにコンポーネントの分割も試してみます。
今回は簡単のため、Appコンポーネントにinputフィールドを記述しました。
inputフィールドが1つの場合は良いかもしれないですが、複数の場合はコンポーネントの分割を検討するのが良いかもしれません。

こんな感じでInputTextのコンポーネントを作ってみました。
InputTextが受け取る引数をPropsで定義しておきます。

import React from 'react';
import styled from 'styled-components';

const Input = styled.input`
  height: 60px;
  width: 450px;
  border: 1px solid #BEBEBE;
  box-sizing: border-box;
  border-radius: 6px;
  padding-left: 16px;
  font-size: 24px;
  color: #222222;
  ::placeholder {
    color: #C1C1C1;
  }
`;

type Props = {
    value: string,
    onChange: (e: React.ChangeEvent<HTMLInputElement>) => void,
    placeholder: string,
};
  
const InputText = (props: Props) => {
  const {
    value,
    onChange,
    placeholder,
  } = props;
  return (
    <Input
      type=""
      value={value}
      placeholder={placeholder}
      onChange={onChange}
    />
  );
};
  
export default InputText;

これをAppコンポーネントで呼び出してあげます。

import React, { useState, useCallback, useMemo } from 'react';
import logo from './logo.svg';
import './App.css';

import InputText from './components/elements/inputText';

const App=()=> {
  const [message, setMessage] = useState('');
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setMessage(e.target.value);
  };
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <InputText
            value={message}
            placeholder="ID"
            onChange={handleChange}
        />
      </header>
    </div>
  );
}

export default App;

こんな感じで簡単にコンポーネントの分割が実現できました。

0
0
0

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?