【问题标题】:Removing inputs leads to incorrect values删除输入会导致不正确的值
【发布时间】:2017-06-07 03:42:10
【问题描述】:

好的,所以问题很简单,但很难解释。

我正在制作一个 InputGenerator 组件,它会生成一个输入列表。

每个生成的输入旁边都有一个相应的“删除”按钮。这两个元素(输入和按钮)被包装在地图函数内的 div 中。 div 有一个唯一的 key 道具。它看起来像这样(这是整个组件的 jsx):

        <div style={[InputGenerator.style.wrapper]}>
            <div className="container" style={InputGenerator.style.container}>
                {this.state.inputs.map((input, idx) => {
                    return (
                        <div key={idx} style={[
                            InputGenerator.style.row,
                            InputGenerator.count > 1 && idx > 0 ? InputGenerator.style.input.pushTop : {},
                        ]}>
                            <InputText
                                id={input.id}
                                name={input.name}
                                placeholder={input.placeholder}
                                style={input.style}
                            />
                            <Button
                                style={InputGenerator.style.remove}
                                type={Button.TYPES.BASIC}
                                icon="ion-close-round"
                                onClick={this.remove.bind(this, input.id)}
                            />
                        </div>
                    );
                })}
            </div>

            <div className="controls" style={InputGenerator.style.controls}>
                <Button icon="ion-plus" type={Button.TYPES.PRIMARY} title="Add ingredient" onClick={this.add.bind(this)}/>
            </div>
        </div>

如您所见,所有输入都保存在 this.state 对象中,并且每个输入都有一个唯一的 id。

以下是添加和删除方法:

添加():

add() {
    InputGenerator.count++;

    const newInput = {
        id: this.id,
        name: this.props.name,
        placeholder: this.props.placeholder,
        style: this.style,
        value: '',
    };

    const inputs = this.state.inputs;

    inputs.push(newInput);

    this.setState({ inputs });
}

删除():

remove(id) {
    this.setState({
        inputs: this.state.inputs.filter(i => i.id !== id),
    });
}

问题是:

  • 我生成三个输入(使用添加按钮)
  • 我将随机值放入输入中(例如:1、2、3)
  • 我点击删除按钮,对应第一个元素(值为 1)
  • 结果:两个输入项,值为 1 和 2
  • 预期:两个输入项,值为 2 和 3
  • 问题:我建议包装 div 上的 key 道具不足以做出反应来跟踪输入的值。

所以,我愿意接受关于如何进行的想法和建议。

这是一个孤立的沙盒,可以用来玩弄我的组件并查看实际的“错误”:https://codesandbox.io/s/5985AKxRB

提前致谢! :)

【问题讨论】:

    标签: reactjs jsx


    【解决方案1】:

    您面临的问题是您没有正确处理状态。更改输入值时需要更新状态。

      handleChange(index,event) {
        let inputs = this.state.inputs;
        inputs[index].value = event.target.value;
        this.setState({inputs:inputs})
      }
    

    演示:DEMO

    这是更新后的代码:

    import React, { Component } from 'react';
        import { render } from 'react-dom';
        import Hello from './Hello';
    
        const styles = {
          fontFamily: 'sans-serif',
          textAlign: 'center',
        };
    
        const App = () =>
          <div style={styles}>
            <InputGenerator />
          </div>;
    
        class InputGenerator extends Component {
          constructor() {
            super();
            this.state = {
              inputs: [],
            };
          }
          componentWillMount() {
            this.add();
          }
          handleChange(index,event) {
            let inputs = this.state.inputs;
            inputs[index].value = event.target.value;
            this.setState({inputs:inputs})
          }
          add() {
            InputGenerator.count++;
    
            const newInput = {
              id: this.id,
              name: this.props.name,
              placeholder: this.props.placeholder,
              style: this.style,
              value: '',
            };
    
            const inputs = this.state.inputs;
    
            inputs.push(newInput);
    
            this.setState({ inputs });
          }
          get id() {
            if (this.props.id) {
              return `${this.props.id}-${InputGenerator.count}`;
            }
    
            return `InputGeneratorItem-${InputGenerator.count}`;
          }
          get style() {
            return [];
          }
          remove(id) {
    
            var state = this.state;
            state.inputs = state.inputs.filter(i => i.id !== id);
            this.setState({
              inputs: state.inputs
            });
          }
          render() {
            return (
              <div>
                <div className="container">
                  {this.state.inputs.map((input, idx) => {
                    return (
                      <div key={idx}>
                        <input
                          id={input.id}
                          name={input.name}
                          value = {input.value}
                          onChange={this.handleChange.bind(this,idx)}
                          placeholder={input.placeholder}
                        />
                        <button onClick={this.remove.bind(this, input.id)}>
                          Remove
                        </button>
                      </div>
                    );
                  })}
                </div>
    
                <div className="controls">
                  <button onClick={this.add.bind(this)}>Add</button>
                </div>
              </div>
            );
          }
        }
    
        InputGenerator.count = 0;
    
        render(<App />, document.getElementById('root'));
    

    【讨论】:

    • 谢谢你,Ved,这正是这样做的方法。再次感谢! :)
    • 欢迎!乐于助人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 2014-07-01
    • 2011-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多