Reactクラスベースのコンポーネントを機能コンポーネントに変換する方法
序章
フックはReactv16.8 の時点で安定しています! フック提案は、開発者がReactに関して抱えているいくつかの主要な懸念に対処する試みです。 基本的に、フックはReact機能に「フック」できる特別な機能です。 以前に機能コンポーネントを作成し、それに状態を追加する必要があることに気付いた場合、フックは理想的です。
Hooksを初めて使用し、概要を知りたい場合は、 ReactHooksの概要を確認してください。
useState
は、状態変数を宣言して、関数呼び出し間で値を保持します。 変数はReactによって保持されます。 useState
は、設定している状態の値を初期化する引数を1つだけ取ります。 useState
を実装することで、this.example
が不要になり、変数に直接アクセスできるようになります。
このチュートリアルでは、以前に作成されたクラスベースのコンポーネントに基づいて構築し、useState
フックを使用してそれを機能コンポーネントに変換します。
前提条件
- プロジェクトのクローンを作成するには、オプションで有効なGitのインストールが必要です。Gitの使用開始を参照してください。
- Node.jsのローカル開発環境。 Node.jsをインストールしてローカル開発環境を作成する方法に従ってください。
- Reactにある程度精通している。 React.jsシリーズのコーディング方法を読むことができます。
このチュートリアルは、ノードv16.4.0、npm
v7.20.3、react
v17.0.2、react-dom
v17.0.2、react-scripts
v4.0.3、 bootstrap
v4.6.0、およびreactstrap
v8.9.0。
ステップ1—プロジェクトの設定
このチュートリアルは、いくつかのスターターコードに基づいています。 スターターコードでは、最新バージョンのreact
とreact-dom
、および reactstrap をインストールして、簡単にフォーマットできるようにしました。
コンポーネントは、email
およびpassword
のフィールドを持つフォームで構成されています。 フォームが送信されると、値がコンソールに記録されます。
まず、ターミナルを開き、作業ディレクトリに移動します。 次に、リポジトリのクローンを作成します。
- git clone https://github.com/do-community/convert-class-to-hook
次に、新しいプロジェクトディレクトリに移動します。
- cd convert-class-to-hook
次に、パッケージの依存関係をインストールします。
- npm install
components
ディレクトリにある現在のClassBasedForm.js
コンポーネントについて理解してください。
import React from 'react'
import {
Form, FormGroup, Input,
Label, Col, Button,
} from 'reactstrap'
export default class ClassBasedForm extends React.Component {
constructor(props) {
super(props)
this.state = {
email: '',
password: '',
}
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
console.log(this.state);
}
render() {
return (
<Form onSubmit={ this.handleSubmit }>
<h1>Class-Based Form</h1>
<FormGroup row>
<Label for="exampleEmail" sm={ 2 }>Email</Label>
<Col sm={ 8 }>
<Input
type="email"
name="email"
id="exampleEmail"
placeholder="email"
value={ this.state.email }
onChange={ (event) => this.setState({ email: event.target.value }) }
/>
</Col>
</FormGroup>
<FormGroup row>
<Label for="examplePassword" sm={ 2 }>Password</Label>
<Col sm={ 8 }>
<Input
type="password"
name="password"
id="examplePassword"
placeholder="password"
value={ this.state.password }
onChange={ (event) => this.setState({ password: event.target.value })}
/>
</Col>
</FormGroup>
<FormGroup check row>
<Col sm={ { size: 'auto', offset: 8 } }>
<Button>Submit</Button>
</Col>
</FormGroup>
</Form>
)
}
};
最後に、アプリケーションを実行してインストールを確認します。
- npm start
ブラウザでアプリケーションを開きます。 メールアドレスとパスワードの値を入力し、フォームを送信します。
この時点で、作業クラスベースのコンポーネントがあります。 クラスベースのコンポーネントを機能コンポーネントに変換する場合、この動作は変更されません。
ステップ2—機能コンポーネントの作成
このセクションでは、components
フォルダーに追加のForm
コンポーネントを作成します。 これはFunctionBasedForm.js
ファイルになります。 このコンポーネントを使用して、useState
フックを使用して同じフォームを作成します。
クラスベースのコンポーネントと新しい機能コンポーネントを並べて使用すると、2つの実装を比較できます。
最初にReactをインポートし、テキストを返すFunctionBasedForm
という関数変数を作成します。 必ずこの関数をエクスポートしてください。
import React from 'react';
const FunctionBasedForm = () => {
return (
<h1>Function Based Form</h1>
)
};
export default FunctionBasedForm;
これをClassBasedForm.js
で使用されているclass ClassBasedForm extends React.Component { ... }
宣言と比較してください。
次に、新しいコンポーネントをApp.js
に追加します。 コードエディタでApp.js
を開きます。
今のところ、以前のClassBasedForm
インポートをコメントアウトします。
FunctionBasedForm
コンポーネントをインポートします。 return
ステートメントで、以前のコンポーネントを新しい<FunctionBasedForm />
コンポーネントに置き換えます。
import React, { Component } from 'react';
import { Container } from 'reactstrap';
// import ClassBasedForm from './components/ClassBasedForm';
import FunctionBasedForm from './components/FunctionBasedForm';
import Logo from './assets/alligator-logo2.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<img src={ Logo } alt="alligator.io logo" width="200" />
<Container>
<FunctionBasedForm />
</Container>
</div>
);
}
}
export default App;
変更を保存して、アプリケーションを実行します。 次に、ブラウザでlocalhost:3000
にアクセスします。
アプリケーションは、新しいコンポーネントからのテキストを表示します。
ステップ3—email
およびpassword
の状態を追加する
元のClassBasedForm.js
コンポーネントでは、コンストラクターを使用して状態を初期化します。 通常のクラスコンポーネントで状態を初期化する必要はなく、フックも必要ありません。 次の例を考えてみましょう。
私たちのほとんどは、次のように状態を初期化することに精通しています。
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
};
}
React 16以降、コンストラクターは不要になりました。 前者は次のようになります。
state = {
email: '',
password: '',
};
機能コンポーネントで、フックを使用できるようになりました。 関数の開始時に、状態と関連するセッターを初期化できます。 これにより、数行のコードが削除される可能性があります。 新しいコンポーネントで状態変数を初期化する方法は次のとおりです。
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
上記の行の1つを分解してみましょう。
const [ email, setEmail] = useState('');
const
:状態と関連する状態変数セッターの両方の変数を作成します。email
:最初の変数email
を初期化して宣言します。setEmail
:変数email
に関連付けられたセッター関数を初期化します。 冗長に見えるかもしれませんが、useState
は単一の値にのみ使用することを目的としています。useState('')
:変数email
が空の文字列として開始することを宣言します。
次に、コードエディタでFunctionBasedForm.js
に戻ります。
ClassBasedForm.js
からコードをコピーし、関数、クリックハンドラー、および状態変数を削除します。
次に、{ useState }
をReactインポートに追加します。 また、前のセクションで定義した状態変数を追加します。
import React, { useState } from 'react';
import {
Form, FormGroup, Input,
Label, Col, Button,
} from 'reactstrap'
const FunctionBasedForm = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
return (
<Form>
<h1>Function Based Form</h1>
<FormGroup row>
<Label for="exampleEmail" sm={ 2 }>Email</Label>
<Col sm={ 8 }>
<Input
type="email"
name="email"
id="exampleEmail"
placeholder="email"
/>
</Col>
</FormGroup>
<FormGroup row>
<Label for="examplePassword" sm={ 2 }>Password</Label>
<Col sm={ 8 }>
<Input
type="password"
name="password"
id="examplePassword"
placeholder="password"
/>
</Col>
</FormGroup>
<FormGroup check row>
<Col sm={ { size: 'auto', offset: 8 } }>
<Button>Submit</Button>
</Col>
</FormGroup>
</Form>
)
};
export default FunctionBasedForm;
変更を保存して、ブラウザでアプリケーションにアクセスします。
この時点で、機能コンポーネントはクラスベースのコンポーネントと視覚的に同一です。
ステップ4—onChange
およびhandleSubmit
の機能を追加する
それでは、フックを利用するように関数を修正しましょう。
クラスベースのコンポーネントで状態を更新した方法をもう一度見てみましょう。
onChange={ (event) => this.setState({ email: event.target.value })
フックを使用すると、状態変数を開始してセッターをアタッチしているため、this
またはthis.setState()
は不要になります。
2つの変数があるため、インライン関数を使用して、入力ごとにuseState
で開始したセッターを呼び出します。 また、this
プレフィックスなしで値を追加し直します。
メールフィールドの場合:
<Input
type="email"
name="email"
id="exampleEmail"
placeholder="email"
value={ email }
onChange={ event => setEmail(event.target.value) }
/>
パスワードフィールドの場合:
<Input
type="password"
name="password"
id="examplePassword"
placeholder="password"
value={ password }
onChange={ event => setPassword(event.target.value) }
/>
それでは、handleSubmit
関数を書き直してみましょう。
関数が以前に作成された方法は次のとおりです。
handleSubmit(e) {
e.preventDefault();
console.log(this.state);
}
注: React 16では、これを矢印関数として記述した場合、コンストラクターでバインドする必要はありません。
次に、関数のconst
を作成する必要があります。 再びデフォルト機能を禁止し、変数を設定し、console.log
それらを設定します。
const handleSubmit = e => {
e.preventDefault();
console.log(email);
console.log(password);
}
これで、handleSubmit
関数をフォームのonSubmit
に追加できます。
新しい機能フックは次のようになります。
import React, { useState } from 'react'
import {
Form, FormGroup, Input,
Label, Col, Button,
} from 'reactstrap'
const FunctionBasedForm = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = event => {
event.preventDefault();
console.log(email);
console.log(password);
}
return (
<Form onSubmit={ handleSubmit }>
<h1>Function Based Form</h1>
<FormGroup row>
<Label for="exampleEmail" sm={ 2 }>Email</Label>
<Col sm={ 8 }>
<Input
type="email"
name="email"
id="exampleEmail"
placeholder="email"
value={ email }
onChange={ event => setEmail(event.target.value) }
/>
</Col>
</FormGroup>
<FormGroup row>
<Label for="examplePassword" sm={ 2 }>Password</Label>
<Col sm={ 8 }>
<Input
type="password"
name="password"
id="examplePassword"
placeholder="password"
value={ password }
onChange={ event => setPassword(event.target.value) }
/>
</Col>
</FormGroup>
<FormGroup check row>
<Col sm={ { size: 'auto', offset: 8 } }>
<Button>Submit</Button>
</Col>
</FormGroup>
</Form>
)
};
export default FunctionBasedForm;
変更を保存して、ブラウザでアプリケーションにアクセスします。
フォームにいくつかの値を追加し、送信ボタンを使用します。 開発ツールを開き、コンソールメッセージを表示します。 email
およびpassword
の値が表示されます。
結論
このチュートリアルでは、以前に作成したクラスベースのコンポーネントに基づいて構築し、useState
フックを使用して機能コンポーネントに変換しました。
ReactプロジェクトにReactフックを適用する方法で学習を続けてください。