React组件中的多个输入,保存每个索引

问题描述 投票:0回答:2

我正在生成随机数的输入,每个输入将收集一个单词。然后,我想获取所有这些单个单词并创建一个单词数组(最终显示该数组)。我是新来的反应者,正在使用onChange作为输入,但是我得到的只是所有单词的斑点。我不知道如何获取每个输入的索引并将其放入提交的数组中。我不知道我应该使用onSubmit还是onChange。我想我不确定如何从提交的每个输入中收集信息。我要同时使用key={index}event.target.value,是否只制作event.target.value的数组?

这里是代码沙箱:

https://codesandbox.io/s/jovial-euler-swfs7?file=/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { Image } from './Image.js'
import { Button } from './Button.js'
import { images } from './assets/images.js'
import { Countdown } from './Countdown.js'
import { DisplayCount } from './DisplayCount.js'
import { Inputs } from './Inputs.js'

class Game extends React.Component{
  constructor(props){
    super(props)

    this.timer = null


    this.state = {
      currentImg: 0,
      timer: null,
      ranNum: null,
      thought: null
    }

    this.handleClick = this.handleClick.bind(this)
  }

countdownClock = async (newRanNum) => {
const startingNum = newRanNum * 20;
for(let i = startingNum; i >= 0; i--) {
    await new Promise(resolve => {
        this.timer = setTimeout(() => {
         this.setState({
           timer: i
         })
        resolve()
     }, 1000)
   });
  }
}

handleChange(event) {
  this.setState({
    thought: event.target.value
  })
}

handleSubmit(event) {

}

generateInputs = (newRanNum) => {
    const inputs = []
    for(let i = 1; i <= newRanNum; i++){
      inputs.push(
        <Inputs type='text' onChange={this.handleChange}  className='textInputs' />
      )
    }
    return inputs;
  }

  handleClick(){
    clearTimeout(this.timer)
    let newRanNum = Math.floor(Math.random() * 20);
    this.countdownClock(newRanNum)
    this.generateInputs(newRanNum)
    let current = this.state.currentImg;
    let next = ++current % images.length;
    this.setState({
      currentImg: next,
      ranNum: newRanNum
    })
  }

  render(){
    let src = this.state.currentImg;
    return(
      <div>
        <Countdown name={'Countdown: '} countdown={this.state.timer} />
        <DisplayCount name='Word Count: ' count={this.state.ranNum} />
        <Image src={images[src]} />
        <Button onClick={this.handleClick} />
        <form onSubmit={this.handleSubmit}>
          <ul>
          {this.generateInputs(this.state.ranNum)}
          </ul>
          <input type='submit' value='Submit' />
        </form>

      </div>
    )
  }
}


ReactDOM.render(
  <Game />,
document.getElementById('root')
);

javascript reactjs forms input state
2个回答
0
投票

这里是一个示例脚本,可让您了解如何处理此问题。当然,有很多方法,包括使用其他库。这不涉及使用任何其他库。

在此处查看演示:https://jsfiddle.net/p0djaw3f/1/

希望这会有所帮助!

Javascript

class SampleApp extends React.Component {

  constructor(props) {
    super(props)

    // Generate Random Number of Inputs. Min of 2
    const inputCount = Math.floor(Math.random() * 5) + 2
    const inputArray = []

    for (let ctr = 0; ctr < inputCount; ctr++) {
        inputArray.push('')
    }

    this.state = {
        inputs: inputArray
    };
  }

  // Capture changes from input[type=text] and update state
  onTextInputChanged(e, index) {
    const inputs = [...this.state.inputs]
    inputs[index] = e.target.value
    this.setState({
        inputs: inputs
    })

  }

  // Display Content in Text Area
  displayContent() {
    const content = this.state.inputs.join('\n')
    const target = document.getElementById('content')
    target.value = content
  }

  render() {

    return (
      <div>
        <h2>Random Inputs</h2>
        <ol>
        {this.state.inputs.map((input, index) => (
          <li key={index}>
            <label>
              <input type="text" value={input} onChange={e => this.onTextInputChanged(e, index)} /> 
            </label>
          </li>
        ))}
        </ol>
        <button onClick={this.displayContent.bind(this)}>Display Content</button>


        <h2>Display Inputs</h2>
        <textarea id="content"></textarea>
      </div>
    )
  }
}

ReactDOM.render(<SampleApp />, document.querySelector("#app"))

HTML

<div id="app"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin: 15px 0 15px 0;
}

input {
  margin-right: 5px;
}

textarea {
  height: 100px;
}

0
投票

通常有两种方法可以做到这一点:

  1. 反应方式
  2. 旧式DOM方式

第二个应该很熟悉:只需通过document.querySelectorAll或类似方法获取所有输入DOM,然后遍历节点列表并通过xx.value获得值

反应方式有点冗长,但也许您应该做什么,关键是使每个输入都成为一个[[受控元素,这意味着输入的值由您传递并由您更新。

    因此,基本上,您应该将所有值存储在您的状态中,您可能应该将其设置为数组,因为您输入的数字太多,无法手写并且可能不确定
  1. 在每个输入上设置onChange处理程序,或将此处理程序委托给祖先以进行更好的设计
  2. 您必须想出一种方法来确定要更新的输入,一个简单的解决方案是在每个输入上添加一个自定义html data-*属性并将其设置为当前索引,您可以在生成输入数组时执行此操作。然后,当您更新时,您将从change事件获取输入索引并更新为值数组中的对应位置
© www.soinside.com 2019 - 2024. All rights reserved.