React
反応の国
サーチ…
基本状態
Reactコンポーネントの状態は、アプリケーションのデータを管理して伝達するために不可欠です。これはJavaScriptオブジェクトとして表され、 コンポーネントレベルのスコープを持ち、 コンポーネントのプライベートデータと考えることができます。
以下の例では、コンポーネントのconstructor
関数でいくつかの初期状態を定義し、それをrender
関数で使用していrender
。
class ExampleComponent extends React.Component {
constructor(props){
super(props);
// Set-up our initial state
this.state = {
greeting: 'Hiya Buddy!'
};
}
render() {
// We can access the greeting property through this.state
return(
<div>{this.state.greeting}</div>
);
}
}
setState()
ReactアプリケーションのUI更新を行う主な方法は、 setState()
関数を呼び出すことです。この関数は、指定した新しい状態と以前の状態との間で浅いマージを実行し、コンポーネントとすべての死体の再描画をトリガーします。
パラメーター
-
updater
:これは、状態にマージされるべき多数のキーと値のペア、またはそのようなオブジェクトを返す関数を持つオブジェクトです。 -
callback (optional)
:setState()
が正常に実行された後に実行される関数。setState()
呼び出しは、Reactによってアトミックになることが保証されていないため、setState()
が正常に実行された後に何らかのアクションを実行したい場合に便利です。
使用法:
setState
メソッドは、状態にマージする必要があるいくつかのキーと値のペアを持つオブジェクトか、 prevState
とprops
から計算されたそのようなオブジェクトを返す関数のどちらかであるupdater
setState
引数を受け入れます。
updater
としてObjectを使用したsetState()
使用
//
// An example ES6 style component, updating the state on a simple button click.
// Also demonstrates where the state can be set directly and where setState should be used.
//
class Greeting extends React.Component {
constructor(props) {
super(props);
this.click = this.click.bind(this);
// Set initial state (ONLY ALLOWED IN CONSTRUCTOR)
this.state = {
greeting: 'Hello!'
};
}
click(e) {
this.setState({
greeting: 'Hello World!'
});
}
render() {
return(
<div>
<p>{this.state.greeting}</p>
<button onClick={this.click}>Click me</button>
</div>
);
}
}
updater
としての関数でのsetState()
使用
//
// This is most often used when you want to check or make use
// of previous state before updating any values.
//
this.setState(function(previousState, currentProps) {
return {
counter: previousState.counter + 1
};
});
これは、 setState()
への複数の呼び出しが使用されるオブジェクト引数を使用する場合よりも安全です。これは、複数の呼び出しをReactで一括処理して一度に実行することができ、現在の小道具を使用して状態を設定する場合の好ましい方法です。
this.setState({ counter: this.state.counter + 1 });
this.setState({ counter: this.state.counter + 1 });
this.setState({ counter: this.state.counter + 1 });
これらの呼び出しは、ReactによってObject.assign()
を使用してバッチ処理され、カウンターが3ではなく1ずつインクリメントされます。
また、機能的アプローチを使用して、状態設定ロジックをコンポーネント外に移動することもできます。これにより、状態ロジックの分離と再利用が可能になります。
// Outside of component class, potentially in another file/module
function incrementCounter(previousState, currentProps) {
return {
counter: previousState.counter + 1
};
}
// Within component
this.setState(incrementCounter);
オブジェクトとコールバック関数を使用してsetState()
を呼び出す
//
// 'Hi There' will be logged to the console after setState completes
//
this.setState({ name: 'John Doe' }, console.log('Hi there'));
共通の反パターン
あなたはstate
props
を保存すべきではありません。それは反パターンと見なされます 。例えば:
export default class MyComponent extends React.Component {
constructor() {
super();
this.state = {
url: ''
}
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({
url: this.props.url + '/days=?' + e.target.value
});
}
componentWillMount() {
this.setState({url: this.props.url});
}
render() {
return (
<div>
<input defaultValue={2} onChange={this.onChange} />
URL: {this.state.url}
</div>
)
}
}
prop url
はstate
で保存され、変更されます。代わりに、変更を状態に保存してから、 state
とprops
両方を使用して完全なパスを作成することを選択します。
export default class MyComponent extends React.Component {
constructor() {
super();
this.state = {
days: ''
}
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({
days: e.target.value
});
}
render() {
return (
<div>
<input defaultValue={2} onChange={this.onChange} />
URL: {this.props.url + '/days?=' + this.state.days}
</div>
)
}
}
なぜなら、Reactアプリケーションでは、真の単一のソースを持ちたいからです。つまり、すべてのデータは1つのコンポーネントの責任であり、1つのコンポーネントだけです。データをその状態内に格納し、データを他のコンポーネントに小道具を介して配布するのは、このコンポーネントの役割です。
最初の例では、MyComponentクラスとその親の両方が、その状態の中で「url」を維持しています。 MyComponentでstate.urlを更新すると、これらの変更は親に反映されません。我々は単一の真実の情報源を失ってしまい、アプリケーションを通じてデータの流れを追跡することがますます困難になっています。これを第2の例と比較すると、urlは親コンポーネントの状態でのみ維持され、MyComponentの支柱として利用されるため、単一の真実のソースを維持します。
状態、イベント、および管理されたコントロール
次に、「管理された」入力フィールドを持つReactコンポーネントの例を示します。入力フィールドの値が変更されるたびに、入力フィールドの新しい値でコンポーネントの状態を更新するイベントハンドラが呼び出されます。イベントハンドラ内でsetState
を呼び出すと、 setState
内のコンポーネントの更新をrender
する呼び出しがトリガされrender
。
import React from 'react';
import {render} from 'react-dom';
class ManagedControlDemo extends React.Component {
constructor(props){
super(props);
this.state = {message: ""};
}
handleChange(e){
this.setState({message: e.target.value});
}
render() {
return (
<div>
<legend>Type something here</legend>
<input
onChange={this.handleChange.bind(this)}
value={this.state.message}
autoFocus />
<h1>{this.state.message}</h1>
</div>
);
}
}
render(<ManagedControlDemo/>, document.querySelector('#app'));
実行時の動作に注意することは非常に重要です。ユーザーが入力フィールドの値を変更するたびに
-
handleChange
が呼び出されます -
setState
が呼び出されます -
render
が呼び出される
ポップクイズ、入力フィールドに文字を入力した後、どのDOM要素が変更されるか
- これらのすべて - トップレベルのdiv、凡例、入力、h1
- 入力とh1のみ
- 何も
- DOMは何ですか?
これをここで試して答えを見つけることができます