ここで3つの答えがあります。使用する(強制される)Reactのバージョン、およびフックを使用するかどうかによって異なります。
まず最初に:
Reactがどのように機能するかを理解することは重要です。それで、物事を適切に実行できるようになります(ヒント:React WebサイトのReactチュートリアル演習を実行するのは非常に価値があります。物)。ここで「適切に」とは、ブラウザーでレンダリングされるアプリケーションインターフェイスを作成していることを意味します。すべてのインターフェース作業は、「Webページを作成している場合に慣れている」ではなく、Reactで行われます(これが、Reactアプリが「Webページ」ではなく「アプリ」である理由です)。
Reactアプリケーションは、次の2つに基づいてレンダリングされます。
- 親がそのコンポーネントのインスタンスを作成したときに宣言されたコンポーネントのプロパティ。親はそのライフサイクルを通じて変更できます。
- コンポーネント自体の内部状態。コンポーネント自体のライフサイクルを通じてそれ自体を変更できます。
あなたが明示しているではない、あなたが反応を使用するときにすることは、HTML要素を生成し、それらを使用している:あなたが言う使用に反応する場合<input>
、例えば、あなたがされていない、あなたが言っている、HTMLの入力要素を作成リアクト入力オブジェクトを作成するために反応これは、たまたまHTML入力要素としてレンダリングされ、そのイベント処理はHTML要素の入力イベントを監視しますが、制御されません。
Reactを使用する場合、実行していることは、ユーザーの操作によってコンポーネントの状態を変更する(多くの場合、操作可能な)データをユーザーに提示するアプリケーションUI要素を生成することです。これにより、アプリケーションインターフェイスの一部の再レンダリングが新しい状態を反映する場合があります。このモデルでは、状態は常に最終的な権限であり、「それをレンダリングするために使用されるUIライブラリー」ではなく、WebではブラウザーのDOMです。DOMは、このプログラミングモデルでほぼ後付けです。Reactがたまたま使用しているのは、特定のUIフレームワークだけです。
したがって、入力要素の場合、ロジックは次のとおりです。
- 入力要素を入力し、
- 入力要素にはまだ何も起こりません。イベントはReactによってインターセプトされ、すぐに終了します。
- Reactは、イベント処理用に設定した関数にイベントを転送します。
- その関数は状態の更新をスケジュールするかもしれません、
- そうである場合、Reactはその状態更新を(非同期で!)実行し
render
、更新後に呼び出しをトリガーしますが、状態更新が状態を変更した場合のみです。
- このレンダリングが行われた後にのみ、UIは「文字を入力した」ことを示します。
これらはすべて、ミリ秒単位で発生します。つまり、「ページで入力要素を使用するだけ」と同じ方法で入力要素に入力したように見えますが、それはまったく同じではありません。起こりました。
それで、それで、Reactの要素から値を取得する方法について:
ES5を使用したReact 15以下
物事を適切に行うために、コンポーネントには状態値があり、それは入力フィールドを介して表示されます。UI要素に変更イベントをコンポーネントに送り返させることで、状態値を更新できます。
var Component = React.createClass({
getInitialState: function() {
return {
inputValue: ''
};
},
render: function() {
return (
//...
<input value={this.state.inputValue} onChange={this.updateInputValue}/>
//...
);
},
updateInputValue: function(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
したがって、ReactにupdateInputValue
関数を使用してユーザーインタラクションを処理しsetState
、状態の更新をスケジュールするために使用するように指示します。render
タップを使用this.state.inputValue
するという事実は、状態の更新後にレンダリングすると、ユーザーは入力した内容に基づいて更新テキストが表示されることを意味します。
コメントに基づく補遺
UI入力が状態値を表す場合(ユーザーがタブを途中で閉じたときに何が起こるかを考えて、タブが復元されます。入力した値をすべて復元する必要がありますか?そうであれば、それが状態です)。そのため、大きなフォームには数十または数百の入力フォームが必要であるように感じるかもしれませんが、ReactはUIを保守可能な方法でモデル化することです。100の独立した入力フィールドがなく、関連する入力のグループがあるため、それぞれをキャプチャしますコンポーネントでグループ化し、「マスター」フォームをグループのコレクションとして作成します。
MyForm:
render:
<PersonalData/>
<AppPreferences/>
<ThirdParty/>
...
これは、巨大な単一フォームコンポーネントよりもはるかに保守が簡単です。状態を維持してグループをコンポーネントに分割します。各コンポーネントは一度にいくつかの入力フィールドの追跡のみを担当します。
また、すべてのコードを書き出すのは「面倒」だと感じるかもしれませんが、それは誤った節約です。将来のあなたも含めて、あなたではない開発者は、明示的に接続されたすべての入力を確認することで、実際に大きなメリットを得ます。コードパスをトレースしやすくなります。ただし、いつでも最適化できます。たとえば、状態リンカーを作成できます
MyComponent = React.createClass({
getInitialState() {
return {
firstName: this.props.firstName || "",
lastName: this.props.lastName || ""
...: ...
...
}
},
componentWillMount() {
Object.keys(this.state).forEach(n => {
let fn = n + 'Changed';
this[fn] = evt => {
let update = {};
update[n] = evt.target.value;
this.setState(update);
});
});
},
render: function() {
return Object.keys(this.state).map(n => {
<input
key={n}
type="text"
value={this.state[n]}
onChange={this[n + 'Changed']}/>
});
}
});
もちろん、これには改善されたバージョンがあるので、https://npmjs.comにアクセスして、最も気に入っているReact状態リンクソリューションを検索してください。オープンソースは主に、他の人がすでに行ったことを見つけ、自分ですべてを最初から作成する代わりにそれを使用することです。
React 16(および15.5トランジショナル)および「モダン」JS
React 16(および15.5からソフトスタート)以降、createClass
呼び出しはサポートされなくなり、クラス構文を使用する必要があります。これは2つのことを変更します。明らかなクラス構文だけでなく、「無料」で実行できるthis
コンテキストバインディングも変更さcreateClass
れるため、引き続きthis
機能するonWhatever
ように、ハンドラーで匿名関数を保持するコンテキストに「太い矢印」表記を使用していることを確認してください。onChange
私たちはここにコードで使用します。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
};
}
render() {
return (
//...
<input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/>
//...
);
},
updateInputValue(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
またbind
、次のように、すべてのイベント処理関数のコンストラクターで使用するのを見たことがあるかもしれません。
constructor(props) {
super(props);
this.handler = this.handler.bind(this);
...
}
render() {
return (
...
<element onclick={this.handler}/>
...
);
}
それをしないでください。
を使用しているほとんどの場合bind
、「あなたはそれを間違っている」ということわざが当てはまります。クラスはすでにオブジェクトプロトタイプを定義しているため、インスタンスコンテキストもすでに定義しています。bind
その上に置かないでください。コンストラクターですべての関数呼び出しを複製するのではなく、通常のイベント転送を使用します。これは、その複製によりバグの表面が増加し、コードを呼び出す場所ではなく、コンストラクターに問題がある可能性があるため、エラーの追跡が非常に困難になるためです。また、作業する(持っている、または選択している)他の人にメンテナンスの負担をかけること。
はい、反応ドキュメントはそれが問題ないと言っていることを知っています。そうではありません、それをしないでください。
React 16.8、フックで関数コンポーネントを使用する
React 16.8以降ではprops
、フックを使用して、関数コンポーネント(つまり、文字通り引数を取る関数を、コンポーネントクラスのインスタンスであるかのように使用できます。クラスを作成する必要はありません)にも状態を指定できます。
完全なクラスコードが必要なく、単一のインスタンス関数が必要な場合は、useState
フックを使用して単一の状態変数とその更新関数を取得できます。これは、上記の例とほぼ同じように機能しますが、setState
関数呼び出し:
import { useState } from 'react';
function myFunctionalComponentFunction() {
const [input, setInput] = useState(''); // '' is the initial state value
return (
<div>
<label>Please specify:</label>
<input value={input} onInput={e => setInput(e.target.value)}/>
</div>
);
}
以前は、クラスと関数コンポーネントの非公式な区別は「関数コンポーネントには状態がない」でしたので、その背後に隠れることはできません。関数コンポーネントとクラスコンポーネントの違いは、非常によく見られるいくつかのページにあります。 -記述された反応のドキュメント(便利な誤解を招くような簡単な説明はありません)。これを読んで、自分が何をしているのかを理解し、自分でプログラミングするための最善の(それが何であれ)ソリューションを選んだかどうかを知ることができます。あなたが抱えている問題から。
this.onSubmit.bind(this);