web-dev-qa-db-ja.com

反応の入力の配列をレンダリングする

私は(より大きなモデルの一部として)一連のメールを持っています。これらは個別の行に表示され、それぞれに[削除]ボタンが付いています(住所自体は、入力ボックスで直接更新できます)。残念ながら、マップ関数を使用して入力がレンダリングされたときに、これをどのように行うかわかりません。 (私は流星炎プロジェクトを流星反応に変換しています)。

すべてが表示されますが、変更イベントにアタッチして、メールの配列を更新できるようにするにはどうすればよいですか?onChange +値を何らかの方法で設定する必要があります。

これはマップ関数です

return this.data.emailGroup.emails.map((email) => {
            return (
                <div key={email} className="input-group">
                    <input type="text" className="form-control" onChange={self.handleEmailListChange} value={email}/>

                    <div className="input-group-btn">
                        <button type="button"
                                className="btn btn-default remove-email"><span
                            className="glyphicon glyphicon-remove"></span></button>
                    </div>
                </div>
            );
        });

初期状態(dbからのデータが入力されます:

 getInitialState() {
      return {
          name : '',
          description: '',
          emails : [],
          newEmailAddress : ''
      }
    },

リクエストに応じて、ここにrenderメソッドがあります(getContentメソッドが必要です。流星ではデータを待機する必要があるため、その間はロード状態が必要なので、getcontentメソッドがあります。

   getContent() {
        return (

            <div className="box box-success">
                <div className="box-header with-border">
                    <h3 className="box-title">List of emails</h3>
                </div>
                <form role="form" className="form-horizontal">
                    <div className="box-body">
                        <p>Below is a list of email addresses which are added to this email group. If
                            you
                            want
                            to add more
                            you can add them one by one by inputting in the box below or add a list into
                            the
                            same box (email
                            addresses have to be seperated by either a space or ;) then press Add to add
                            to
                            the
                            list. You can edit
                            the addresses directly as well as remove them.</p>
                        <div className="input-group">
                            <input type="text" className="form-control"

                                   value={this.state.newEmailAddress}
                                   onChange={this.handleAddNewEmail}
                                   placeholder="Email addresses seperated by a space or a semicolon ; i.e. [email protected];[email protected]"/>
                    <span className="input-group-btn">
                      <button type="button" onClick={this.handleAddNewEmailButton} className="btn btn-info btn-flat add-email">Add</button>
                    </span>
                        </div>
                        <br/>
                        {this.renderEmail()}
                    </div>
                </form>
            </div>
        )
    },
    render()
    {
    var contentStyle = {
        minHeight : '946px'
    };
        return (
            <div className="content-wrapper" style={contentStyle}>
                <section className="content-header">
                    <h1>
                        {this.data.emailGroup? this.data.emailGroup.name : 'hello'}
                    </h1>
                    <small> Created by: Christian Klinton</small>
                    <br/>
                    <small> Last updated by: Christian Klinton - 2015-11-12 08:10:11</small>
                    <ol className="breadcrumb">
                        <li><a href="/emailGroups"><i className="fa fa-dashboard"></i> Home</a></li>
                        <li><a href="/emailGroups">Email groups</a></li>
                        <li className="active">{this.data.emailGroup? this.data.emailGroup.name : 'loading'}</li>
                    </ol>
                </section>
                <section className="content">
                    <div className="row">
                        <div className="col-md-6">
                            <div className="box box-primary">
                                <div className="box-header with-border">
                                    <h3 className="box-title">Information</h3>

                                </div>
                                <form role="form">
                                    <div className="box-body">
                                        <div className="form-group">
                                            <label htmlFor="inputName">Name</label>
                                            <input type="email" className="form-control" id="name"
                                                   onChange={this.handleNameChange}
                                                   placeholder="Set the name of the email group" autoComplete="off"
                                                  value={this.state.name}/>
                                        </div>

                                        <div className="form-group">
                                            <label>Description</label>
                                    <textarea className="form-control" rows="3" id="description"
                                              placeholder="Enter a description what and how the template is used..."
                                              onChange={this.handleDesriptionChange}
                                              value={this.state.description}
                                    ></textarea>
                                        </div>


                                    </div>
                                </form>
                            </div>
                        </div>
                        <div className="col-md-6">
                            {this.data.emailGroup? this.getContent() : <p>Loading</p> }
                        </div>
                        <div className="form-group">
                            <div className="col-sm-offset-8 col-sm-4">
                                <div className="pull-right">
                                    <button className="btn btn-primary">Delete all</button>
                                    <button className="btn btn-primary save">Save</button>
                                </div>
                            </div>
                        </div>
                    </div>
                </section>
            </div>
        )
    }
9
Todilo

Reactでは、レンダリングされた配列のすべての要素に固有のものが必要です。これはkeyと呼ばれ、属性です。

キーに何を割り当てるかわからない場合は、配列のインデックスを割り当てます。

this.props.doors.map((door, index) => (
    <div key={index} className="door"></div>
));

これはあなたの問題に適用された同じ解決策です:

return this.data.emailGroup.emails.map((email, index) => {
    return (
        <div key={index} className="input-group">
            <input type="text"
                   className="form-control"
                   onChange={self.handleEmailListChange.bind(this, index)} value={email}/>
        </div>
    );
});

変更された電子メールのインデックスを受け取るためにhandleEmailListChangeをバインドしたことに注意してください。 handleEmailListChangeがインデックスを受け入れると、変更された電子メールを状態内で更新できます。

handleEmailListChange: function(index, event) {
    var emails = this.state.emails.slice(); // Make a copy of the emails first.
    emails[index] = event.target.value; // Update it with the modified email.
    this.setState({emails: emails}); // Update the state.
}
11
Moshe Revah

render()関数内にArray.mapを直接配置する必要があります。各配列要素が親要素(ここでは<div>)内にラップされ、一意のkey={}が必要であることに注意してください

class ArrayMap extends React.Component{
  //your functions
  handleEmailChanged(key){
    // Handle email
  }
  render(){
    return(
      <div>
        {
          this.data.emailGroup.emails.map((email) => {
            <div key={email.key}>
              <button onClick={this.handleEmailChanged.bind(this,email.key)}/>
            </div>
          });
        }
      </div>
    );
  }
}
2

あなたが探しているのは次のようなものだと思います:

MyPage = React.createClass({
  mixins: [ReactMeteorData],

  getMeteorData() {
    // ...
  },

  render() {
    const emails = this.data.emailGroup.emails.map((email) => {
      return (
        <div key={email} className="input-group">
          <input type="text" className="form-control"
                 onChange={this.handleEmailListChange} value={email} />

          <div className="input-group-btn">
            <button type="button"
                    className="btn btn-default remove-email"><span
              className="glyphicon glyphicon-remove" /></button>
          </div>
        </div>
      );
    });

    return <div>
      {emails}
    </div>
  }
});

selfthisに変更しました。 ES6の矢印関数を使用しているため、self = thisを割り当てる必要はありません。

1
ffxsam