删除输入会导致不正确的值
Removing inputs leads to incorrect values
好的,所以问题很简单,但很难解释。
我正在制作一个 InputGenerator 组件,它生成一个输入列表。
每个生成的输入旁边都有一个对应的 "remove" 按钮。这两个元素(输入和按钮)包装在映射函数内的 div 中。 div 有一个独特的关键道具。看起来像这样(这是整个组件的 jsx):
<div style={[InputGenerator.style.wrapper]}>
<div className="container" style={InputGenerator.style.container}>
{this.state.inputs.map((input, idx) => {
return (
<div key={idx} style={[
InputGenerator.style.row,
InputGenerator.count > 1 && idx > 0 ? InputGenerator.style.input.pushTop : {},
]}>
<InputText
id={input.id}
name={input.name}
placeholder={input.placeholder}
style={input.style}
/>
<Button
style={InputGenerator.style.remove}
type={Button.TYPES.BASIC}
icon="ion-close-round"
onClick={this.remove.bind(this, input.id)}
/>
</div>
);
})}
</div>
<div className="controls" style={InputGenerator.style.controls}>
<Button icon="ion-plus" type={Button.TYPES.PRIMARY} title="Add ingredient" onClick={this.add.bind(this)}/>
</div>
</div>
如您所见,所有输入都保存在 this.state 对象中,每个输入都有一个唯一的 ID。
添加和删除方法如下:
添加():
add() {
InputGenerator.count++;
const newInput = {
id: this.id,
name: this.props.name,
placeholder: this.props.placeholder,
style: this.style,
value: '',
};
const inputs = this.state.inputs;
inputs.push(newInput);
this.setState({ inputs });
}
删除():
remove(id) {
this.setState({
inputs: this.state.inputs.filter(i => i.id !== id),
});
}
问题是:
- 我生成三个输入(使用添加按钮)
- 我在输入中放入了随机值(例如:1、2、3)
- 我点击删除按钮,对应第一个元素(值为1)
- 结果:两个输入项的值为 1 和 2
- 预期:两个输入项的值为 2 和 3
- 问题:我建议包装上的 key 道具 div 不足以做出反应来跟踪输入的值。
所以,我愿意听取如何进行的想法和建议。
这里有一个独立的沙箱,可以试用我的组件并查看 "bug" 的运行情况:https://codesandbox.io/s/5985AKxRB
提前致谢! :)
您遇到的问题是因为您没有正确处理状态。更改输入值时需要更新状态。
handleChange(index,event) {
let inputs = this.state.inputs;
inputs[index].value = event.target.value;
this.setState({inputs:inputs})
}
演示:DEMO
这是更新后的代码:
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
const styles = {
fontFamily: 'sans-serif',
textAlign: 'center',
};
const App = () =>
<div style={styles}>
<InputGenerator />
</div>;
class InputGenerator extends Component {
constructor() {
super();
this.state = {
inputs: [],
};
}
componentWillMount() {
this.add();
}
handleChange(index,event) {
let inputs = this.state.inputs;
inputs[index].value = event.target.value;
this.setState({inputs:inputs})
}
add() {
InputGenerator.count++;
const newInput = {
id: this.id,
name: this.props.name,
placeholder: this.props.placeholder,
style: this.style,
value: '',
};
const inputs = this.state.inputs;
inputs.push(newInput);
this.setState({ inputs });
}
get id() {
if (this.props.id) {
return `${this.props.id}-${InputGenerator.count}`;
}
return `InputGeneratorItem-${InputGenerator.count}`;
}
get style() {
return [];
}
remove(id) {
var state = this.state;
state.inputs = state.inputs.filter(i => i.id !== id);
this.setState({
inputs: state.inputs
});
}
render() {
return (
<div>
<div className="container">
{this.state.inputs.map((input, idx) => {
return (
<div key={idx}>
<input
id={input.id}
name={input.name}
value = {input.value}
onChange={this.handleChange.bind(this,idx)}
placeholder={input.placeholder}
/>
<button onClick={this.remove.bind(this, input.id)}>
Remove
</button>
</div>
);
})}
</div>
<div className="controls">
<button onClick={this.add.bind(this)}>Add</button>
</div>
</div>
);
}
}
InputGenerator.count = 0;
render(<App />, document.getElementById('root'));
好的,所以问题很简单,但很难解释。
我正在制作一个 InputGenerator 组件,它生成一个输入列表。
每个生成的输入旁边都有一个对应的 "remove" 按钮。这两个元素(输入和按钮)包装在映射函数内的 div 中。 div 有一个独特的关键道具。看起来像这样(这是整个组件的 jsx):
<div style={[InputGenerator.style.wrapper]}>
<div className="container" style={InputGenerator.style.container}>
{this.state.inputs.map((input, idx) => {
return (
<div key={idx} style={[
InputGenerator.style.row,
InputGenerator.count > 1 && idx > 0 ? InputGenerator.style.input.pushTop : {},
]}>
<InputText
id={input.id}
name={input.name}
placeholder={input.placeholder}
style={input.style}
/>
<Button
style={InputGenerator.style.remove}
type={Button.TYPES.BASIC}
icon="ion-close-round"
onClick={this.remove.bind(this, input.id)}
/>
</div>
);
})}
</div>
<div className="controls" style={InputGenerator.style.controls}>
<Button icon="ion-plus" type={Button.TYPES.PRIMARY} title="Add ingredient" onClick={this.add.bind(this)}/>
</div>
</div>
如您所见,所有输入都保存在 this.state 对象中,每个输入都有一个唯一的 ID。
添加和删除方法如下:
添加():
add() {
InputGenerator.count++;
const newInput = {
id: this.id,
name: this.props.name,
placeholder: this.props.placeholder,
style: this.style,
value: '',
};
const inputs = this.state.inputs;
inputs.push(newInput);
this.setState({ inputs });
}
删除():
remove(id) {
this.setState({
inputs: this.state.inputs.filter(i => i.id !== id),
});
}
问题是:
- 我生成三个输入(使用添加按钮)
- 我在输入中放入了随机值(例如:1、2、3)
- 我点击删除按钮,对应第一个元素(值为1)
- 结果:两个输入项的值为 1 和 2
- 预期:两个输入项的值为 2 和 3
- 问题:我建议包装上的 key 道具 div 不足以做出反应来跟踪输入的值。
所以,我愿意听取如何进行的想法和建议。
这里有一个独立的沙箱,可以试用我的组件并查看 "bug" 的运行情况:https://codesandbox.io/s/5985AKxRB
提前致谢! :)
您遇到的问题是因为您没有正确处理状态。更改输入值时需要更新状态。
handleChange(index,event) {
let inputs = this.state.inputs;
inputs[index].value = event.target.value;
this.setState({inputs:inputs})
}
演示:DEMO
这是更新后的代码:
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
const styles = {
fontFamily: 'sans-serif',
textAlign: 'center',
};
const App = () =>
<div style={styles}>
<InputGenerator />
</div>;
class InputGenerator extends Component {
constructor() {
super();
this.state = {
inputs: [],
};
}
componentWillMount() {
this.add();
}
handleChange(index,event) {
let inputs = this.state.inputs;
inputs[index].value = event.target.value;
this.setState({inputs:inputs})
}
add() {
InputGenerator.count++;
const newInput = {
id: this.id,
name: this.props.name,
placeholder: this.props.placeholder,
style: this.style,
value: '',
};
const inputs = this.state.inputs;
inputs.push(newInput);
this.setState({ inputs });
}
get id() {
if (this.props.id) {
return `${this.props.id}-${InputGenerator.count}`;
}
return `InputGeneratorItem-${InputGenerator.count}`;
}
get style() {
return [];
}
remove(id) {
var state = this.state;
state.inputs = state.inputs.filter(i => i.id !== id);
this.setState({
inputs: state.inputs
});
}
render() {
return (
<div>
<div className="container">
{this.state.inputs.map((input, idx) => {
return (
<div key={idx}>
<input
id={input.id}
name={input.name}
value = {input.value}
onChange={this.handleChange.bind(this,idx)}
placeholder={input.placeholder}
/>
<button onClick={this.remove.bind(this, input.id)}>
Remove
</button>
</div>
);
})}
</div>
<div className="controls">
<button onClick={this.add.bind(this)}>Add</button>
</div>
</div>
);
}
}
InputGenerator.count = 0;
render(<App />, document.getElementById('root'));