【问题标题】:Why is my React show/hide label not updating correctly?为什么我的 React 显示/隐藏标签没有正确更新?
【发布时间】:2018-03-20 02:59:30
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: reactjs input label jsx textinput


    【解决方案1】:

    您的错误似乎在您的 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 的控制台日志,因为在下一个生命周期之前状态尚未完全更新。相反,控制台会在您的渲染方法中记录状态。

    【讨论】:

    • 嗨,斯科特,感谢您的提示!这很有帮助。我尝试调试,textChanged(index) 的函数引用 this.textInput.value 与正确的数组索引不匹配。你知道我是否可以为每个输入字段设置特定的 ref id/classname,因为我正在使用 {this.state.arr.map(renderItem, this)} 来渲染 renderItem() 中的重复组件
    • 是的,您可以为每个输入字段设置特定的参考值。你想要多少就多少。我回答了你的问题吗,你能接受我的回答吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多