删除输入组件时反应错误 [英] React error when removing input component

查看:46
本文介绍了删除输入组件时反应错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定这是否是反应问题,但我在这个问题上很挣扎.我试图创建一个简单的例子来发布我的项目:

https://codepen.io/as3script/pen/VMbNdz?editors=1111

示例中有四个按钮.

要重现问题,请按前三个按钮中的每一个以创建文本输入并输入值.例如,在第一个中输入 100,在第二个中输入 200,在第三个中输入 300.现在按第四个按钮删除第一个输入.

它应该保留第二个和第三个各自的值,200 和 300,但它在第二个中显示 100,在第三个中显示 200.

<小时>

此代码与 CodePen 上的代码相同,只是不允许在没有此代码的情况下发布链接.

class ButtonComponent extends React.Component {构造函数(道具){超级(道具);this.state = {filtersArr:[]}this.addButtons = this.addButtons.bind(this);this.removeButtons = this.removeButtons.bind(this);this.getInput = this.getInput.bind(this);this.onChangeHandler = this.onChangeHandler.bind(this);}添加按钮(e){让 tempArr = this.state.filtersArr;tempArr.push({comp:this.getInput(e.target.id), id:e.target.id});this.setState({filtersArr:tempArr});}删除按钮(e){console.log(e.target.id);让 newArr = this.state.filtersArr.filter((filter)=>{返回 (filter.id !=='FirstButton')})this.setState({filtersArr:newArr});}onChangeHandler(e){console.log(e.target.value);}获取输入(ID){返回 (<div><h6>{id}</h6><输入身份证=分钟"类型=文本"占位符=分钟"onChange={this.onChangeHandler}/>

)}使成为() {让样式 = {显示:'内联块'}返回 (<div><p>添加三个按钮并在每个输入中输入数字,并删除amt.</p><button id="FirstButton" onClick={this.addButtons}>FirstButton</button><button id="SecondButton" onClick={this.addButtons}>SecondButton</button><button id="ThirdButton" onClick={this.addButtons}>ThirdButton</button><button id="FirstButton" onClick={this.removeButtons}>移除 firstButton</button><ul>{this.state.filtersArr.map((filter, index)=>{return <li style={styles} key={index}>{filter.comp}</li>})}

);}}ReactDOM.render(<按钮组件/>,document.getElementById('root'));

解决方案

问题是你使用数组索引作为你的key,所以React会重用前两个li 元素并删除最后一个.将 key={index} 更改为 key={filter.id},它会按您的预期工作.

关于评论的更新 &否决:我假设实际代码中过滤器的唯一性,因为该字段被称为 id.CodePen 似乎更像是一个精简版来显示问题.但是,如果您确实希望让每个按钮创建多个文本字段,您确实需要添加一些额外的东西来区分键(例如计数器).不过,这不会影响问题中所述的问题.

再次查看代码,我注意到 getInput 将是提取到单独(无状态)组件中的理想候选者,例如过滤器输入.与将子渲染保持在组件状态相比,这更适合 React 模型.

I am not sure if it´s a react issue or not but I am struggling a lot with this issue. I tried to create just a simple example to post out of my project:

https://codepen.io/as3script/pen/VMbNdz?editors=1111

There are four buttons on the example.

To reproduce the problem press each of the first three buttons to create a text input from and enter a value. For example enter 100 into the first one, 200 into the second and 300 into the third. Now press the fourth button to remove the first input.

It should keep the second and third with their respective values, 200 and 300, but instead it´s showing 100 in the second and 200 in the third.


This code is the same as it is on CodePen, it just didn't allow the link to be posted without this.

class ButtonComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {filtersArr:[]}
    this.addButtons = this.addButtons.bind(this);
    this.removeButtons = this.removeButtons.bind(this);
    this.getInput = this.getInput.bind(this);
    this.onChangeHandler = this.onChangeHandler.bind(this);
  }

   addButtons(e){     
    let tempArr = this.state.filtersArr;

    tempArr.push({comp:this.getInput(e.target.id), id:e.target.id});

    this.setState({filtersArr:tempArr});
  }

  removeButtons(e){
    console.log(e.target.id);
    let newArr = this.state.filtersArr.filter((filter)=>{
      return (filter.id !=='FirstButton')
    })
    this.setState({filtersArr:newArr});
  }

  onChangeHandler(e){
    console.log(e.target.value);
  }

  getInput(id){
    return (
      <div>
        <h6>{id}</h6>
        <input
          id="min"
          type="text"
          placeholder="min"
          onChange={this.onChangeHandler}/>
      </div>
    )
  }

  render() {
    let styles = {
      display:'inline-block'
    }

    return (
      <div>
        <p>Add three buttons and enter the number in each input, and remove amt.</p>
        <button id="FirstButton" onClick={this.addButtons}>FirstButton</button>
        <button id="SecondButton" onClick={this.addButtons}>SecondButton</button>
        <button id="ThirdButton" onClick={this.addButtons}>ThirdButton</button>

        <button id="FirstButton" onClick={this.removeButtons}>Remove firstButton</button>

          <ul>
            {this.state.filtersArr.map((filter, index)=>{
              return <li style={styles} key={index}>{filter.comp}</li>
            })
            }
          </ul>
      </div>
    );
  }
}

ReactDOM.render(
  <ButtonComponent/>,
  document.getElementById('root')
);

解决方案

The problem is that you're using the array index as your key, so React will reuse the first two li elements and drop the last one. Change key={index} to key={filter.id}, and it works as you would expect.

Update concerning the comment & downvote: I assumed uniqueness on filters in the actual code, given that the field is called id. The CodePen seems more of a stripped down version to show the problem. But if you do actually wish to let each button create multiple text fields, you'd indeed need to add something extra to distinguish the keys (e.g. a counter). This doesn't affect the problem as stated in the question though.

Looking at the code again, I noticed getInput would be an ideal candidate to extract into a separate (stateless) component, e.g. FilterInput. This fits better with the react model than keeping child renderings in the component state.

这篇关于删除输入组件时反应错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆