为什么我的React显示/隐藏标签没有正确更新?
问题描述:
标签是可编辑的:单击标签时,将显示输入文本字段并隐藏标签字段。在文本字段丢失焦点后,将显示标签字段并隐藏文本字段。我有问题标签不更新与新的文本输入值。为什么我的React显示/隐藏标签没有正确更新?
添加组件按钮将创建一个新组件并将其放置在列表顶部。有问题,新创建的组件位于显示输入文本和标签隐藏的列表下方。
添加了多个新组件后,当我点击其中一个标签时,文本字段会自动更新为其他文本。我试图调试它,但无法解决它。
import React from 'react';
import FontAwesome from 'react-fontawesome';
export default class Dynamic extends React.Component {
constructor() {
super();
this.state = {
arr: [],
text:"LABEL",
saveDisabled: true,
editing: []
};
}
handleSort(sortedArray) {
this.setState({
arr: sortedArray
});
}
save(){
}
closePopup() {
}
handleAddElement() {
this.textInput.value : 'LABEL';
this.state.arr.unshift('LABEL');
this.setState({
saveDisabled: false,
});
}
handleRemoveElement(index) {
const newArr = this.state.arr.slice();
newArr.splice(index, 1);
this.setState({
arr: newArr,
saveDisabled: false
});
}
changeLabel(index){
this.setState({
saveDisabled: false
});
console.log(index);
this.state.editing[index] = true;
console.log("changelabel");
}
textChanged(index) {
console.log("txtval: "+this.textInput.value);
this.setState({ text: this.textInput.value});
this.state.arr[index] = this.textInput.value;
this.setState({
arr: arr
});
console.log(this.state.arr);
}
inputLostFocus(index) {
this.state.editing[index] = false;
}
keyPressed(event) {
if(event.key == 'Enter') {
this.inputLostFocus();
}
this.inputLostFocus();
console.log("key");
}
render() {
function renderItem(num, index) {
return (
<DemoItem className="dynamic-item" >
<FontAwesome className='th' name=' th' onClick={this.handleRemoveElement.bind(this, index)}/>
<div name="name" className={(index==0)||this.state.editing[index] ? "hideElement": "displayElement"} onClick={this.changeLabel.bind(this,index)}>{this.state.arr[index]}</div>
<input autofocus name="name" type="text" className={(index==0)||this.state.editing[index] ? "displayElement": "hideElement"} onChange={this.textChanged.bind(this, index)} onBlur={this.inputLostFocus.bind(this,index)}
onKeyPress={this.keyPressed.bind(this,index)} defaultValue={this.state.arr[index]} ref={(input) => {this.textInput = input;}} />
<FontAwesome className='trash-o' name='trash-o' onClick={this.handleRemoveElement.bind(this, index)}/>
</DemoItem>
)
}
return (
<div className="demo-container">
<div className="dynamic-demo">
<h2 className="demo-title">
Tasks
<button disabled={this.state.saveDisabled} onClick={::this.save}>Save</button>
<button onClick={::this.handleAddElement}>Add Component</button>
</h2>
<Sortable className="vertical-container" direction="vertical" dynamic>
{this.state.arr.map(renderItem, this)}
</Sortable>
</div>
</div>
);
}
}
displayElement {
display: inline;
}
.hideElement{
display: none;
}
答
它看起来像你的错误是在你的textChanged
功能,试试这个:
textChanged(index) {
console.log("txtval: " + this.textInput.value);
// this.state.arr[index] = this.textInput.value; <= bug
const newArray = [...this.state.arr];
newArray[index] = this.textInput.value;
this.setState({
arr: newArray,
text: this.textInput.value
});
// console.log(this.state.arr); <= don't check here, check in your render method
}
两个变化:
- 通过
this.setState
修改状态,不通过this.state.arr
。 - 设置状态在一个
this.setState
行动为更干净的代码。 - 注释掉this.state的控制台日志,因为直到下一个生命周期,状态还没有完全更新。相反,控制台在您的渲染方法中记录状态。
嗨斯科特,谢谢你的提示!这很有帮助。我尝试debug,textChanged(index)的函数引用this.textInput.value,它与正确的数组索引不匹配。你知道我是否可以为每个输入字段设置特定的ref id/classname,因为我使用{this.state.arr.map(renderItem,this)}来呈现renderItem()中重复的组件。 – user21
是的,你可以为每个输入字段设置特定的参考值。尽可能多的你想要的。我回答了你的问题吗?你能接受我的回答吗? – Scott