为什么我的React显示/隐藏标签无法正确更新?

时间:2017-10-09 00:21:24

标签: reactjs input label jsx textinput

标签可编辑:单击标签时,将显示输入文本字段并隐藏标签字段。文本字段失去焦点后,将显示标签字段并隐藏文本字段。我有问题,标签不会使用新的文本输入值更新。

添加组件按钮将创建一个新组件并将其置于列表顶部。遇到问题,新创建的组件位于列表下方,该列表显示输入文本并标记为隐藏。

添加多个新组件后,当我单击其中一个标签时,文本字段会自动更新为其他文本。我试图调试它但无法解决它。

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;
}  

1 个答案:

答案 0 :(得分:1)

您的textChanged函数看起来像是您的错误,请尝试以下方式:

&#13;
&#13;
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
}
&#13;
&#13;
&#13;

两个变化:

  1. 通过this.setState修改状态,而不是通过this.state.arr
  2. 在一个this.setState操作中设置状态以获得更干净的代码。
  3. 注释掉this.state的控制台日志,因为状态尚未完全更新,直到下一个生命周期。相反,控制台会在渲染方法中记录状态。