web-dev-qa-db-ja.com

Reactで複数の入力制御コンポーネントを編集するにはどうすればよいですか?

連絡先オブジェクトを状態として保存するコンポーネントがあります-{firstName: "John"、lastName: "Doe"、phone: "1234567890}このオブジェクトを編集するフォームを作成しますが、入力に値を保持する場合元の接触パラメーターの場合、各入力を制御コンポーネントにする必要がありますが、状態が{contact:{...}}のみを保持するため、各パラメーターに調整するhandleChange関数を作成する方法がわかりません。以下は私が現在持っているものです-

  getInitialState: function () {
    return ({contact: {}});
  },
  handleChange: function (event) {
    this.setState({contact: event.target.value });
  },
  render: function () {
    return (
        <div>
          <input type="text" onChange={this.handleChange} value={this.state.contact.firstName}/>
          <input type="text" onChange={this.handleChange} value={this.state.contact.lastName}/>
          <input type="text" onChange={this.handleChange} value={this.state.contact.lastName}/>
        </div>
      );
    }

私は私のハンドルを変えたい

  handleChange: function (event) {
    this.setState({contact.firstName: event.target.value });
  }
29
akantoword

これを行うための「単純な」方法と「スマートな」方法があります。あなたが私に尋ねるなら、物事をスマートな方法で行うことは必ずしも最善ではありません。この場合、両方とも非常に理解しやすいものです。

サイドノート:考えてほしいことの1つは、contactオブジェクトを更新する必要があるか、またはfirstNameなどを直接状態のままにしておくことができるかということです。コンポーネントの状態のデータがたくさんあるのでしょうか?その場合は、責任をより狭くして、より小さなコンポーネントに分割することをお勧めします。

「シンプルな」方法

  changeFirstName: function (event) {
    const contact = this.state.contact;
    contact.firstName = event.target.value;
    this.setState({ contact: contact });
  },
  changeLastName: function (event) {
    const contact = this.state.contact;
    contact.lastName = event.target.value;
    this.setState({ contact: contact });
  },
  changePhone: function (event) {
    const contact = this.state.contact;
    contact.phone = event.target.value;
    this.setState({ contact: contact });
  },
  render: function () {
    return (
      <div>
        <input type="text" onChange={this.changeFirstName.bind(this)} value={this.state.contact.firstName}/>
        <input type="text" onChange={this.changeLastName.bind(this)} value={this.state.contact.lastName}/>
        <input type="text" onChange={this.changePhone.bind(this)} value={this.state.contact.phone}/>
      </div>
    );
  }

「スマート」な方法

  handleChange: function (propertyName, event) {
    const contact = this.state.contact;
    contact[propertyName] = event.target.value;
    this.setState({ contact: contact });
  },
  render: function () {
    return (
      <div>
        <input type="text" onChange={this.handleChange.bind(this, 'firstName')} value={this.state.contact.firstName}/>
        <input type="text" onChange={this.handleChange.bind(this, 'lastName')} value={this.state.contact.lastName}/>
        <input type="text" onChange={this.handleChange.bind(this, 'phone')} value={this.state.contact.lastName}/>
      </div>
    );
  }



更新:ES2015 +を使用した同じ例

このセクションには、上記と同じ例が含まれていますが、ES2015 +の機能を使用しています。

ブラウザ間で次の機能をサポートするには、 Babel を使用してコードを変換する必要があります。プリセット es2015 および react 、およびプラグイン stage-

以下に更新された例を示します。 object destructuring を使用して状態から連絡先を取得し、 spread operator を使用して、既存のオブジェクトを変更する代わりに更新された連絡先オブジェクトを作成し、コンポーネントを作成します- クラスReact.Component を拡張し、 矢印関数 を使用してコールバックを作成することで、bind(this)が不要になります。

「シンプルな」方法、ES2015 +

class ContactEdit extends React.Component {

  changeFirstName = (event) => {
    const { contact } = this.state;
    const newContact = {
      ...contact,
      firstName: event.target.value
    };
    this.setState({ contact: newContact });
  }
  changeLastName = (event) => {
    const { contact } = this.state;
    const newContact = {
      ...contact,
      lastName: event.target.value
    };
    this.setState({ contact: newContact });
  }
  changePhone = (event) => {
    const { contact } = this.state;
    const newContact = {
      ...contact,
      phone: event.target.value
    };
    this.setState({ contact: newContact });
  }

  render() {
    return (
      <div>
        <input type="text" onChange={this.changeFirstName} value={this.state.contact.firstName}/>
        <input type="text" onChange={this.changeLastName} value={this.state.contact.lastName}/>
        <input type="text" onChange={this.changePhone} value={this.state.contact.phone}/>
      </div>
    );
  }
}

「スマート」な方法、ES2015 +

handleChangeForカリー化された関数 であることに注意してください。propertyNameで呼び出すと、コールバック関数が作成され、呼び出されると、状態の(新しい)連絡先オブジェクトの[propertyName]が更新されます。

class ContactEdit extends React.Component {

  handleChangeFor = (propertyName) => (event) => {
    const { contact } = this.state;
    const newContact = {
      ...contact,
      [propertyName]: event.target.value
    };
    this.setState({ contact: newContact });
  }

  render() {
    return (
      <div>
        <input type="text" onChange={this.handleChangeFor('firstName')} value={this.state.contact.firstName}/>
        <input type="text" onChange={this.handleChangeFor('lastName')} value={this.state.contact.lastName}/>
        <input type="text" onChange={this.handleChangeFor('phone')} value={this.state.contact.lastName}/>
      </div>
    );
  }
}
60
ArneHugo

ES6ワンライナーアプローチ

<input type="text" 
       value={this.state.username}
       onChange={(e) => this.setState({ username: e.target.value })}
       id="username"/>
8
Stuart P.

ネストされたオブジェクトの状態を更新するには、2つの方法があります。

  1. JSON.parse(JSON.stringify(object))を使用してオブジェクトのコピーを作成し、コピーを更新してsetStateに渡します。
  2. react-addonsの不変性ヘルパー を使用します。これは推奨される方法です。

これがどのように機能するかを見ることができます JS Fiddle 。コードは次のとおりです。

var Component = React.createClass({
    getInitialState: function () {
    return ({contact: {firstName: "first", lastName: "last", phone: "1244125"}});
  },
  handleChange: function (key,event) {
    console.log(key,event.target.value);

    //way 1 
    //var updatedContact = JSON.parse(JSON.stringify(this.state.contact));
    //updatedContact[key] = event.target.value;

    //way 2 (Recommended)
    var updatedContact = React.addons.update(this.state.contact, {
        [key] : {$set: event.target.value}
    });
    this.setState({contact: updatedContact});
  },
  render: function () {
    return (
        <div>
          <input type="text" onChange={this.handleChange.bind(this,"firstName")} value={this.state.contact.firstName}/>
          <input type="text" onChange={this.handleChange.bind(this,"lastName")} value={this.state.contact.lastName}/>
          <input type="text" onChange={this.handleChange.bind(this,"phone")} value={this.state.contact.phone}/>
        </div>
      );
    }
});

ReactDOM.render(
  <Component />,
  document.getElementById('container')
);
2
Mark

これが一般的なものです。

handleChange = (input) => (event) => {
    this.setState({
        ...this.state,
        [input]: event.target.value
    });
}

そして、このように使用します。

<input handleChange ={this.handleChange("phone")} value={this.state.phone}/>
1
MmtBkn

最も近いアプローチ

以下は、単純なアプリケーションで使用したアプローチです。これは React で推奨されるアプローチであり、本当にすっきりしています。 ArneHugoの答えに非常に近く、私もhmに感謝します。アイデアは、そのフォームとリアクションフォームサイトを組み合わせたものです。各フォーム入力のname属性を使用して、特定のpropertyNameを取得し、それに基づいて状態を更新できます。これは、上記の例のES6での私のコードです。

class ContactEdit extends React.Component {

  handleChangeFor = (event) => {
    const name = event.target.name;
    const value = event.target.value;
    const { contact } = this.state;
    const newContact = {
      ...contact,
      [name]: value
    };
    this.setState({ contact: newContact });
  }

  render() {
    return (
      <div>
        <input type="text" name="firstName" onChange={this.handleChangeFor} />
        <input type="text" name="lastName" onChange={this.handleChangeFor}/>
        <input type="text" name="phone" onChange={this.handleChangeFor}/>
      </div>
    );
  }
}

違い:

  • 状態を値属性として割り当てる必要はありません。値は必要ありません
  • OnChangeメソッドは、代わりにname属性を使用するため、関数呼び出し内に引数を持つ必要はありません。
  • Begeningで各入力の名前と値を宣言し、それらを使用してコード内で状態を適切に設定し、名前のラケットを属性として使用します。

ここではコードが少なく、フォームから任意の種類の入力を取得するスマートな方法があります。name属性には入力ごとに一意の値があるためです。作業中の を参照してください。初期段階の実験的なブログアプリケーション用にCodPenにあります。

1
azad6026

<input>要素には多くの場合、nameというプロパティがあります。イベントハンドラーから受け取るイベントオブジェクトからこの名前プロパティにアクセスできます。

一般化された変更ハンドラを書く

constructor () {
    super();
    this.state = {
      name: '',
      age: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange (evt) {      
    this.setState({ [evt.target.name]: evt.target.value });
  }

render () {
    return (
      <form>

        <label>Name</label>
        <input type="text" name="name" onChange={this.handleChange} />

        <label>Age</label>
        <input type="text" name="age" onChange={this.handleChange} />

      </form>
    );
  }

ソース

0
Dhruv Raval
handleChange(event){
    this.setState({[event.target.name]:event.target.value});
    this.setState({[event.target.name]:event.target.value});
  }
0
Karan Chunara