javascript - 基于动态复选框和文本输入的 setState 数组
问题描述
我正在开发一个在 react js 中的 UI,我正在从我从 API 获得的数据生成一个动态表,在左侧我有复选框,每个复选框都有一个特定的文本类型输入,这些输入是动态生成的就像声明的那样。我要存档的是,一旦选中用户复选框,我需要生成一个具有以下 4 个字段的对象isChecked
(以检查复选框是否被选中),module_id
(如果选中,则我需要获取模块 ID) , isUpdated
(这是用于跟踪对特定输入文本所做的任何更改,如果不是,则应为零),discount_price
(如果isUpdated
为真,则我需要此值)。这些事情我试图通过setState
在 react js 中实现。
上面定义的对象的必要性是为了在后端处理数据。根据我将编写查询的条件,我希望我对我的陈述问题很清楚。
我已经在类组件的构造函数中初始化了对象状态,我已经将 handleChange 方法与复选框和文本的输入绑定在一起,但是我遇到了错误TypeError: Cannot read property 'checked' of undefined
,我想知道处理这种动态表单的最佳方法。
constructor(){
super();
this.state = {moduleData: [], modules : [] }
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
这是我的 handleChange 函数
handleChange(event) {
const key = event.target.dataset.moduleindex;
const modId = event.target.dataset.moduleid;
const inputKeyType = event.target.type;
var is_updated = 1;
if(inputKeyType == 'checkbox'){
var inputChecked = !this.state.modules[key].checked;
if (!this.state.modules[key].checked == false) {
is_updated = 0;
}
} else {
var inputChecked = true;
is_updated = 1;
}
this.setState({
modules: {
...this.state.modules,
[key]: {
["isChecked"]: inputChecked,
["module_id"]: modId,
["isUpdated"]: is_updated,
["discount_price"]: event.target.value,
}
}
});
}
这是动态生成的表
const moduleRow = modules.map((module, index) => (
<tr key={module.id.toString()}>
<th scope="row" width="" className='text-center' >
<Input type="checkbox"
className="checkbox"
name="module_id"
data-moduleindex = {index}
data-moduleid = {module.id}
checked={
this.state.modules[index]
? this.state.modules[index].checked
: ""
}
onChange={this.handleChange}
/>
</th>
<td>
{module.module_name}
</td>
<td>
{module.module_short_code}
</td>
<td>
{module.limits}
</td>
<td>
{ module.subscriptionInterval === 'monthly' ? module.monthly_price : module.annual_price }
</td>
<td>
<Input
type="text"
name="discount_price"
data-moduleindex = {index}
id = {module.id}
onChange={this.handleChange}
value={
this.state.modules[index]
? this.state.modules[index].discount_price
: ""
}
/>
</td>
<td>
{this.getStatus(module.status)}
</td>
</tr>
));
最后我想得到这样的对象数组
[
0:{"isChecked":true, "module_id":2, "isUpdated" : 1, "discount_price": 5 },
1:{"isChecked":false, "module_id":3, "isUpdated" : 1, "discount_price": 5 },
2: {"isChecked":true, "module_id":8, "isUpdated" : 0, "discount_price": "" }
]
这可以实现还是我错过了什么?请帮忙
解决方案
你的问题就在这里;
if(inputKeyType == 'checkbox'){
var inputChecked = !this.state.modules[key].checked;
if (!this.state.modules[key].checked == false) {
is_updated = 0;
}
}
this.state.modules
初始化时将是一个空数组。您正在使用checked
而不是isChecked
. 所有复选框都以 false 开头,例如;
if(inputKeyType === 'checkbox'){
var inputChecked = this.state.modules[key] ? !this.state.modules[key].isChecked : true
if (inputChecked === false) {
is_updated = 0;
}
} else {
var inputChecked = true;
is_updated = 1;
}
this.state.modules
也以数组开始,最终将其分配为setState
. 因此,在您的构造函数中,我会将模块初始化为空对象
而且在输入类型中也需要这样做
<Input type="checkbox"
className="checkbox"
name="module_id"
data-moduleindex = {index}
data-moduleid = {module.id}
checked={
this.state.modules[index]
? this.state.modules[index].isChecked
: ""
}
onChange={this.handleChange}
/>
推荐阅读
- android - 使用 Android NDK 构建 C++ 项目
- android - Xamarin.Android:工具栏未按预期显示
- angular - 将值从 typescript 传递到 routerlink
- javascript - 用javascript中的结果替换公式
- azure - C# Application Insight 失败:TrackEvent 未发送到 Azure Application Insight
- logic - 0-100智能玩家评分系统
- scala - 识别 Apache-Flink 中哪个对象不可序列化
- spring - 具有“密码”授权类型的“/oauth/token”端点不支持“POST”
- vue.js - Nativescript-slides 插件 + Vue
- mysql - 每个月的第 31 天都在下个月以下。例如 5 月 31 日在 6 月以下