我有一个表格中数据的输入表单,根据有多少列生成输入。我正在努力分离输入但是当我在一个中更改一个值时,所有输入都会发生变化。有什么方法可以区分它们,以便我可以在每个输入中输入不同的值。我正在使用React和flux。
以下是我目前正在使用的代码:
import React from 'react';
import AppStore from '../../stores/AppStore';
export default class RowForm extends React.Component {
state = {input: ''};
onChange = (e) => {
this.setState({input: e.target.value});
console.log(input);
};
editStop = () => {
this.props.editStop();
};
handleSubmit = (e) => {
e.preventDefault();
let access_token = AppStore.getToken();
let id = AppStore.getTable().id;
this.props.handleSubmit(access_token, id);
};
render() {
let {input} = this.state;
let dataEntries = AppStore.getTable().columns; //this gets the amount of columns so I can map through them and generate the correct amount of inputs.
return (
<tr>
{dataEntries.map((element, index) => {
return (
<td key={index}><input type="text" className="form-control" id={element.id} placeholder="enter data" value={this.state.input} onChange={this.onChange} /></td>
);
})}
<td>
<button className="btn btn-default" onClick={this.editStop}><i className="fa fa-ban"></i>Cancel</button>
<button className="btn btn-success" onClick={this.handleSubmit}><i className="fa fa-check"></i>Save</button>
</td>
</tr>
);
}
}
非常感谢任何帮助,尤其是示例!
感谢您的时间
答案 0 :(得分:1)
您可以在onChange
处理程序中创建匿名函数:
<input key={index} onChange={event => this.onChange(event, index)}/>
但是,更大的问题是您没有将AppStore.getTable().columns
映射到任何地方,因此根本无法修改组件状态。此外,您正在使用React不正确地使用ES6类。
class RowForm extends React.Component {
constructor (props) {
super(props);
this.state = {
inputs: {0: null, 1: null, 2: null}
};
}
onChange (event, index) {
this.setState({inputs[index]: event.target.value});
}
}
如果您需要映射AppStore.getTable().columns
,则应将该数据作为道具传递下来。将道具映射到州是一种反模式。
class App extends React.Component {
constructor () { // initialize stuff... }
componenDidMount () {
this.setState({columns: AppStore.getTable().columns});
}
onChange (event, index) {
this.setState({columns[index]: event.target.value});
}
render () {
<RowForm columns={this.state.columns} handleChange={this.onChange}/>
}
}
class RowForm extends React.Component {
constructor (props) {
super(props);
}
render () {
<div>
{this.props.columns.map(index => {
return <input onChange={event => this.props.handleChange(event, index)}/>
})}
</div>
}
}
但是,在调用AppStore
时,这不会更新onChange
。为此你需要以某种方式跟踪全球状态。我建议您查看Redux。
更新了使用当前条件尝试修复代码的答案:
class RowForm extends React.Component {
// Set `dataEntries` to an empty array. This will prevent errors
// from appearing in between `render` and `componentDidMount`.
// e.g.: `this.state.dataEntries.map` is undefined or not an Array.
// You may want to make this a little bit more fail safe though.
state = {dataEntries: []};
onChange = (event, element) => {
// This assumes `element` is a string based on the column name.
this.setState({dataEntries[element]: event.target.value});
}
componentDidMount () {
// Set state with columns from the table.
// Whenever this component mounts it will reset to the state
// from `AppStore` unless you set up event listeners like in
// Flux or migrate to Redux
// This also assumes that `getTable().columns` returns an array
// of column names. I don't know what your data structure looks
// like so it's hard for me to help here. You need to turn the
// array into an object to store values in the keys.
let dataEntries = AppStore.getTable().columns.reduce((obj, name) => {
obj[name] = null;
return obj;
}, {});
this.setState({dataEntries});
}
render () {
let {dataEntries} = this.state;
// It is not really recommended to use indexes here because
// of the way React diffing works. If `element` is a string
// you can use that as the key/index instead. Also, it needs
// to be unique within the array.
// Turn dataEntries back into an array so map will work properly.
return (
<tr>
{Object.keys(dataEntries).map((element) => {
return (
<td key={element}><input type="text" className="form-control" id={element} placeholder="enter data" value={dataEntries[element]} onChange={event => this.onChange(event, element)} /></td>
);
})}
<td>
<button className="btn btn-default" onClick={this.editStop}><i className="fa fa-ban"></i>Cancel</button>
<button className="btn btn-success" onClick={this.handleSubmit}><i className="fa fa-check"></i>Save</button>
</td>
</tr>
);
}
}