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
コンポーネントについて理解してください。
src / 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
という関数変数を作成します。 必ずこの関数をエクスポートしてください。
src / components / FunctionBasedForm.js
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 />
コンポーネントに置き換えます。
src / App.js
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インポートに追加します。 また、前のセクションで定義した状態変数を追加します。
src / components / FunctionBasedForm.js
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
に追加できます。
新しい機能フックは次のようになります。
src / components / FunctionBasedForm.js
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フックを適用する方法で学習を続けてください。