如何使用ReactJS从动态创建的输入中获取值

时间:2018-05-24 21:33:11

标签: javascript forms reactjs ecmascript-6

  

例如,基于一段时间,我在页面中添加了输入   如果周期为一周,如果周期为,我将有7个文本输入   两个星期我将有15个文本输入我已经完成它不是   问题现在我想获得在创建的文本中输入的值   知道在我的渲染中只有一个输入的字段   根据给定的时间重复多次

     

这是我渲染输入的方式

render() {
    const days = [];
    let day = this.props.StartOfWeek;
    while (day <= this.props.EndOfWeek) {
      days.push(moment(day).format('ddd, DD-MM'));
      day = day.clone().add(1, 'd');
    }
    const daysCode = days.map((displayedDay) => {
    return (
        <td className={this.isWeek(displayedDay)}>
          <tr>{displayedDay}</tr>
          <tr>  <input type="text" key={displayedDay.id} size="3" /></tr>
        </td>);
    });

关于如何进行的任何想法?

2 个答案:

答案 0 :(得分:1)

最简单的方法,使用箭头功能:

class InputsList extends React.Component {

    render() {
        const items = this.props.fields.map((field, i) => (
            <YourInputComponent onChange={
                (e) => this.props.onChange(i, e.target.value) } />
        );

        return (<div>{ items }</div>);
    }
} 

这种方法的问题是每次调用render时,onChange内的箭头函数都会重新分配一个新函数。这可能会导致性能问题:

  • Pure Components将再次渲染,因为旧的(箭头)函数和新的(箭头)函数会有所不同,甚至认为两者都调用完全相同的函数。
  • 垃圾收集器开销以摆脱那些旧功能。

更好的方法是将任何相关数据传递给YourInputComponentonChange将负责使用相关索引/ id调用class InputsList extends React.Component { render() { const items = this.props.fields.map((field, i) => ( <YourInputComponent index={ i } onChange={ this.props.onChange } /> ); return (<div>{ items }</div>); } } ,以便您识别触发事件的输入。

YourInputComponent

this.props.onChange(this.props.index, e.target.value); 中,您将拥有以下内容:

onChange

现在,传递给YourInputComponent的函数将始终相同,只要它在父组件中没有更改,因此class List extends React.PureComponent { render() { const { values, length } = this.props; const items = []; for (let i = 0; i < length; ++i) { const value = values[i]; items.push(<li key={ `${ value }-${ i }` } className="list__item">{ value }</li>); } return (<ul>{ items }</ul>); } } class InputsList extends React.PureComponent { render() { const { name, label, totalInputs, onChange } = this.props; const inputs = []; for (let i = 0; i < totalInputs; ++i) { inputs.push( <li key={ i }> <label className="inputs__label"> { `${ label } ${ i + 1 }` } <input className="inputs__input" type='text' name={ `${ name }-${ i }` } onInput={ (e) => onChange(i, e.target.value) } /> </label> </li> ); } return (<ul>{ inputs }</ul>); } } class RadioTabs extends React.PureComponent { render() { const { name, value, options, onChange } = this.props; const radios = options.map(option => ( <li key={ option }> <label className="radioTabs__label"> <input className="radioTabs__input" type="radio" value={ option } checked={ value === option } name={ name } onChange={ onChange } /> <span className="radioTabs__text">{ option }</span> </label> </li> )); return( <ul className="radioTabs__base"> { radios } </ul> ); } } class App extends React.Component { static options = [1, 2, 3, 4, 5, 6, 7]; constructor(props) { super(props); this.state = { totalInputs: App.options[0], values: [], }; } onTotalInputsChange = (e) => { this.setState({ totalInputs: parseInt(e.target.value), values: this.state.values, }); }; onInputsChange = (index, value) => { const values = [ ...this.state.values ]; values[index] = value; this.setState({ totalInputs: this.state.totalInputs, values, }); }; render() { const { totalInputs, values } = this.state; return( <div className="app"> <div className="header"> <RadioTabs name="days" value={ totalInputs } options={ App.options } onChange={ this.onTotalInputsChange } /> </div> <div className="columns"> <div className="left"> <InputsList name="values" totalInputs={ totalInputs } label="Day" onChange={ this.onInputsChange } /> </div> <div className="right"> <List values={ values } length={ totalInputs }/> </div> </div> </div> ); } } ReactDOM.render(<App />, document.getElementById('app'));将不会被重新呈现。

这里有第一个方法的工作示例:

body {
  font-family: monospace;
  margin: 0;
}

ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.app {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.header {
  padding: 4px;
  border-bottom: 2px solid black;
  flex: 0 0 auto;
}

.columns {
  display: flex;
  flex: 1 1 auto;
}

.left,
.right {
  flex: 1 0 0;
  overflow-y: scroll;
  padding: 4px;
}

.left {
  border-right: 2px solid black;
}

/* RADIO TABS */

.radioTabs__base {
  display: flex;
  align-items: center;
}
.radioTabs__label {
  display: block;
  padding: 4px 0;
  cursor: pointer;
  border-radius: 2px;
  min-height: 27px;
  min-width: 35px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.radioTabs__label:hover {
  background: #EEE;
}

.radioTabs__input {
  display: none;
}

.radioTabs__text {
  display: block;
  padding: 2px 4px 0;
  border-bottom: 2px solid transparent;
}

.radioTabs__input:checked + .radioTabs__text {
  border-bottom-color: black;
}

/* INPUTS LIST */

.inputs__label {
  display: block;
  padding: 4px 8px;
  cursor: pointer;
  border-radius: 2px;
  display: flex;
  align-items: center;
}

.inputs__label:hover {
  background: #EEE;
}

.inputs__input {
  border: 2px solid black;
  padding: 4px 8px;
  margin: 0 0 0 8px;
  font-family: monospace;
  flex: 1 0 auto;
}

/* LIST */

.list__item {
  border-bottom: 2px solid black;
  line-height: 33px;
  height: 33px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
<div id="app"></div>

<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
Dim Arr_TextStat = {TextBox1, TextBox2, TextBox3, TextBox4, TextBox5, Textbox6}
For each TextBoxM in Arr_TextStat
Select Case TextBoxM.Text 

Case >20 
ws.Cells(y, 1).Value = Me.Controls("Textbox" & y - j).Value

y = y + 1
j = j - 1

Case > 14 
ws.Cells(ay, 1).Value = Me.Controls("Textbox" & ay - aw).Value

ay = ay + 1
aw = aw - 1

End select
Next

答案 1 :(得分:0)

我发现解决方案很愚蠢,使用jquery

  $('.App input').each((index, input) => {
  alert(input.value);

}