为什么我的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 
 
}

两个变化:

  1. 通过this.setState修改状态,不通过this.state.arr
  2. 设置状态在一个this.setState行动为更干净的代码。
  3. 注释掉this.state的控制台日志,因为直到下一个生命周期,状态还没有完全更新。相反,控制台在您的渲染方法中记录状态。
+0

嗨斯科特,谢谢你的提示!这很有帮助。我尝试debug,textChanged(index)的函数引用this.textInput.value,它与正确的数组索引不匹配。你知道我是否可以为每个输入字段设置特定的ref id/classname,因为我使用{this.state.arr.map(renderItem,this)}来呈现renderItem()中重复的组件。 – user21

+0

是的,你可以为每个输入字段设置特定的参考值。尽可能多的你想要的。我回答了你的问题吗?你能接受我的回答吗? – Scott