我的表包含多行,并且每行的最后一列都有一个下拉列表,其中包含3个值 Incomplete , Fail 和 Pass 。如果将下拉列表选择为“通过”,那么我需要显示选中标记图标,如果将下拉列表选择为“失败”,则将显示错误图标。
以上逻辑似乎运行良好。我正在努力的是如何只针对表的特定行而不对其他行产生任何影响。我只想将图标显示在我要定位的行上(在本例中为第1行)。
与其他“失败”选项类似:
这是我的代码:
this.state = {
...
test_steps: [],
status: ""
};
selectStatus(e) {
var selected = $('.status_list option:selected').text();
if(selected == "Pass") {
this.setState({status: e.target.value})
$('.checkmark').show();
$('.bug').hide();
$(".checkmark").css({"display": "inline", "marginLeft": "10px"});
} else if(selected == "Fail") {
this.setState({status: e.target.value})
$('.bug').show();
$('.checkmark').hide();
$(".bug").css({"display": "inline", "marginLeft": "10px"});
} else {
this.setState({status: e.target.value})
$('.checkmark').hide();
$('.bug').hide();
}
}
tsteps = test_steps.map((testStep, index) => {
return (
<tr key={index}>
<td>{testStep.step_number}</td>
<td>{testStep.description}</td>
<td>{testStep.expected_results}</td>
<td>{testStep.other_info}</td>
<td>
<select
className="status_list form-control"
id="status"
onChange={this.selectStatus.bind(this)} // calling selectStatus function
>
<option className={styles.emptyVal}></option>
<option>Incomplete</option>
<option>Fail</option>
<option>Pass</option>
</select>
<div className="checkmark" style={{display: 'none'}}>
<i className={`fas fa-check ${styles.check_icon}`}></i>
</div>
<div className="bug" style={{display: 'none'}}>
<i className={`fas fa-bug ${styles.bug_icon}`}></i>
</div>
{testStep.status}
</td>
</tr>
);
});
更新的代码:
this.state = {
test_steps: [],
status: []
};
selectStatus(event, index) {
this.setState(oldState => {
const newStatus = oldState.status.slice();
newStatus[index] = event.target.value;
return {
status: newStatus
};
});
};
tsteps = test_steps.map((testStep, index) => {
return (
<tr key={index}>
<td>{testStep.step_number}</td>
<td>{testStep.description}</td>
<td>{testStep.expected_results}</td>
<td>{testStep.other_info}</td>
<td>
<select
className="status_list form-control"
value={this.state.status[index]}
onChange={e => this.selectStatus(e, index)} >
<option className={styles.emptyVal}></option>
<option>Incomplete</option>
<option>Fail</option>
<option>Pass</option>
</select>
{this.state.status[index] === "Pass" &&
<div className="checkmark">
<i className={`fas fa-check ${styles.check_icon}`}></i>
</div>
}
{this.state.status[index] === "Fail" &&
<div className="bug">
<i className={`fas fa-bug${styles.bug_icon}`}></i>
</div>
}
{testStep.status}
</td>
</tr>
);
});
我遇到的错误: 未捕获的TypeError:无法读取null的属性“值”
答案 0 :(得分:0)
您不应该使用jquery手动更改dom。 React不知道您正在这样做,因此您将通过使React无法正确协调dom来制造错误。
相反,您应该使用react的组件状态,然后根据该状态呈现所需的内容。您已经在使用状态来跟踪步骤,您只需要添加状态,然后使用该状态进行渲染即可。因此,请增加您的状态,如下所示:
this.state = {
...
test_steps: [],
status: [] <--- now an array
};
然后在渲染时,执行以下操作:
test_steps.map((testStep, index) => {
return (
<tr key={index}>
// some components omitted
<select
className="status_list form-control"
value={this.state.status[index]} <-- now taken from state
onChange={e => this.selectStatus(e, index)} >
// options omitted
</select>
{this.state.status[index] === "Pass" &&
<div className="checkmark">
<i className={`fas fa-check ${styles.check_icon}`}></i>
</div>
}
{this.state.status[index] === "Fail" &&
<div className="bug">
<i className={`fas fa-bug${styles.bug_icon}`}></i>
</div>
}
{testStep.status}
</tr>
);
});
在上面的代码中,我使selectStatus期望有一个索引,因此这是selectStatus将如何使用该索引的方法:
selectStatus(event, index) {
this.setState(oldState => {
const newStatus = oldState.status.slice();
newStatus[index] = event.target.value;
return {
status: newStatus
};
});
};
编辑:要修复null错误,有两个选项。首先,我们可以同步保存我们关心的值,以便异步代码运行时可用
selectStatus(event, index) {
const val = event.target.value;
this.setState(oldState => {
const newStatus = oldState.status.slice();
newStatus[index] = val;
return {
status: newStatus
};
});
};
或者我们可以告诉react保存事件对象,而不是重用它。
selectStatus(event, index) {
event.persist();
this.setState(oldState => {
const newStatus = oldState.status.slice();
newStatus[index] = event.target.value;
return {
status: newStatus
};
});
};