我开始使用一个应用程序,它需要根据下拉列表中的选择动态生成输入框。这是我的代码:
import React, { Component } from "react";
import "./App.css";
import { Container, Row, Col, Input, Button, Fa, Card, CardBody } from "mdbreact";
class App extends Component {
constructor(props) {
super(props);
this.state = {
numberOfUnits: 0,
name: {
valid: true,
value: "",
label: "Property Nickname",
length: 0,
css: "grey-text"
},
address: {
valid: true,
value: "",
label: "Property Address",
length: 0,
css: "grey-text"
},
city: {
valid: true,
value: "",
label: "Property City",
length: 0,
css: "grey-text"
},
numberOfUnits: {
valid: true,
value: "",
label: "Property City",
length: 0,
css: "grey-text"
}
};
this.saveData = this.saveData.bind(this);
this.setUnitNumber = this.setUnitNumber.bind(this);
}
setUnitNumber() {
let currentComponent = this;
var localUnitCount = document.getElementById("inputNumberOfUnits").value;
currentComponent.setState({ numberOfUnits: localUnitCount });
}
saveData() {
let currentComponent = this;
var validData = true;
var localName = {
valid: true,
value: "",
label: "Property Nickname",
length: 0,
css: "grey-text"
};
var localAddress = {
valid: true,
value: "",
label: "Property Nickname",
length: 0,
css: "grey-text"
};
var localCity = {
valid: true,
value: "",
label: "Property City",
length: 0,
css: "grey-text"
};
// validate the property nickname
localName.value = document.getElementById("lblName").value;
localName.length = localName.value.length;
if (localName.length < 5) {
validData = false;
localName.valid = false;
localName.label =
"You did not enter a property nickname (minimum of 5 charaters)";
localName.css = "text-danger";
}
// validate the property address
localAddress.value = document.getElementById("lblAddress").value;
localAddress.length = localAddress.value.length;
if (localAddress.length < 3) {
validData = false;
localAddress.valid = false;
localAddress.label =
"You did not enter a property Address (minimum of 5 characters)";
localAddress.css = "text-danger";
}
// validate the property city
localCity.value = document.getElementById("lblCity").value;
localCity.length = localCity.value.length;
if (localCity.length < 3) {
validData = false;
localCity.valid = false;
localCity.label =
"You did not enter a property city (minimum of 3 characters)";
localCity.css = "text-danger";
}
currentComponent.setState({
name: localName,
city: localCity,
address: localAddress
});
}
renderData = () => {
let currentComponent = this;
var localUnitCount = this.state.numberOfUnits;
var idArray = [];
var idObject = {
counter: 0,
idName: ""
};
for (var counter = 0; counter < localUnitCount; counter++) {
var unitName = "Unit";
if (counter < 10) {
unitName = unitName + "0";
}
unitName = unitName + (counter + 1);
idObject.counter = counter + 1;
idObject.idName = unitName;
idArray[counter] = idObject;
console.log("idArray[counter]: ", idArray[counter]);
}
console.log(idArray);
return idArray.map(item => (
<div>
<div className="oldscanFont">
<label> Unit {item.counter} </label>
</div>
<hr />
</div>
));
};
render() {
return (
<div className="App">
<div className="d-flex flex-wrap justify-content-center position-absolute w-100 h-50 align-items-center align-content-center">
<Container>
<Row>
<Col md="6">
<Card>
<CardBody>
<form>
<p className="h4 text-center py-4">Sign up</p>
<div className={this.state.name.css}>
<Input
id="lblName"
label={this.state.name.label}
group
type="text"
/>
</div>
<div className={this.state.address.css}>
<Input
id="lblAddress"
label={this.state.address.label}
group
type="text"
/>
</div>
<div className={this.state.city.css}>
<Input
id="lblCity"
label={this.state.city.label}
group
type="text"
/>
</div>
<div className={this.state.numberOfUnits.css}>
<div class="input-group mb-3">
<div class="input-group-prepend">
<label
class="input-group-text"
for="inputNumberOfUnits"
>
Number of Units
</label>
</div>
<select
class="custom-select"
id="inputNumberOfUnits"
onChange={() => {
this.setUnitNumber();
}}
>
<option value="1" selected>
One
</option>
<option value="2">Two</option>
<option value="3">Three</option>
<option value="4">Four</option>
<option value="5">Five</option>
<option value="6">Six</option>
<option value="7">Seven</option>
<option value="8">Eight</option>
<option value="9">Nine</option>
<option value="10">Ten</option>
<option value="11">Eleven</option>
<option value="12">Twelve</option>
<option value="13">Thirteen</option>
<option value="14">Fourteen</option>
<option value="15">Fifteen</option>
<option value="16">Sixteen</option>
<option value="17">Seventeen</option>
<option value="18">Eighteen</option>
<option value="19">Nineteen</option>
<option value="20">Twenty</option>
</select>
</div>
</div>
<div>{this.renderData()}</div>
<div className="text-center py-4 mt-3">
<Button
color="cyan"
onClick={() => {
this.saveData();
}}
>
Save
</Button>
</div>
</form>
</CardBody>
</Card>
</Col>
</Row>
</Container>
</div>
</div>
);
}
}
export default App;
当我运行代码,并从下拉列表中选择4时,应用程序应动态生成4个元素。代码不完整但由于某种原因,当我构建发送到map函数的数组时,该数组在每个实例中包含相同的数据。下面是我从下拉列表中选择4后应用程序和console.log的屏幕截图:
正如您在console.log中看到的那样,似乎正在正确构建idArray,但最终的console.log显示了包含相同计数器和idName值的idArray的所有4个实例。然后,当渲染执行并且我输出{item.counter}时,每个元素包含相同的值。
知道为什么会这样吗?
谢谢。
我发现renderData
方法的这一部分相当有趣。
...
for (var counter = 0; counter < localUnitCount; counter++) {
var unitName = "Unit";
if (counter < 10) {
unitName = unitName + "0";
}
unitName = unitName + (counter + 1);
idObject.counter = counter + 1;
idObject.idName = unitName;
idArray[counter] = idObject;
console.log("idArray[counter]: ", idArray[counter]);
}
idObject
正在进行修改,而不是作为副本。
这可以写成。
...
var idNamePrefix = "Unit";
for (var counter = 0, unitName; counter < localUnitCount; counter++) {
if (counter < 10) {
unitName = idNamePrefix + "0";
} else {
unitName = idNamePrefix + (counter + 1);
}
idArray.push(
// make object with idObject key-values applied.
// more importantly, the last object replaces the count and idName value.
Object.assign({}, idObject, {counter: counter + 1, idName: unitName})
)
}