简体   繁体   中英

Adding and removing input fields in Reactjs with values not reseting

Hi i am working on a React application where there are four options.when a user select an option corresponding input element will be added to the wrapper.In the following code add operation works fine but remove operation is not working properly ,it is not removing the corresponding element.Another problem the values on the inputs fields not present when the component re-renders.so experts guide me how i can acheive removing the corresponding row when the remove button is clicked and the input values should not be reset when the component re-renders

import React from 'react';
import ReactDOM from 'react-dom';

var fields = "";
var options = ['one','two','three','four','five','six','seven','eight','nine','Ten','eleven','twelve'];

var SelectOptions = React.createClass({
    render:function(){
        var options = this.props.options;
        return (
             <select>
                   {options.map(function(col,index){
                       return (
                         <option key={index} value ={col}> {col} </option>
                       );
                   })}
             </select>
        );

    }
});

var PriceMultiply = React.createClass({
    render:function(){
        return (
           <tr>
             <td>
               Adjust Price Multiply
             </td>
             <td>
               Multiply <SelectOptions options={options} />
             </td>
             <td>
               by <input type="text" name="" />
             </td>
             <td>
               <button className="btn btn-danger" onClick={this.props.removeOperation} > Remove </button>
             </td>
           </tr>           
        );
    }
});

var PriceAdd = React.createClass({
    render:function(){
        return (
           <tr>
             <td>
               Adjust Price (Add)
             </td>
             <td>
               Add <input type="text" name="" />
             </td>
             <td>
               to <SelectOptions options={options} />
             </td>
             <td>
               <button className="btn btn-danger" onClick={this.props.removeOperation} > Remove </button>
             </td>
           </tr>           
        );
    }
});

var ExcludeProducts = React.createClass({
    render:function(){
        return (
           <tr>
             <td>
               Filter Products (Includes) 
             </td>
             <td>
               Exclude Products Where <SelectOptions options={options} />
             </td>
             <td>
              Includes  <input type="text" name="" />
             </td>
             <td>
               <button className="btn btn-danger" onClick={this.props.removeOperation} > Remove </button>
             </td>
          </tr>             
        );
    }
});

var IncludeProducts = React.createClass({
    render:function(){
        return (
           <tr>
             <td>
               Filter Products (Includes) 
             </td>
             <td>
               Exclude Products Where <SelectOptions options={options} />
             </td>
             <td>
              does not equals <input type="text" name="" />
             </td>
             <td>
               <button className="btn btn-danger" onClick={this.props.removeOperation} > Remove </button>
             </td>
          </tr>
        );
    }
});

var DynamicFields = React.createClass({
    getInitialState:function(){
       return {
          operations:[]
       }
    },
    removeOperation:function(index){
        var operations = this.state.operations;
        operations.splice(index,1);
        this.setState({operations:operations});
    },
    addOperation:function(){
         var value = this.refs.operationsDropDown.value;
         this.setState({operations:this.state.operations.concat([value])});
    },
    renderAdjustmentRows:function(){

       fields = this.state.operations.map((operation,index) =>{
              if(operation == "adjust-price-multiply"){
                    return (<PriceMultiply key={index} removeOperation={this.removeOperation} />);
              }else if(operation == "adjust-price-add"){
                     return (<PriceAdd key={index} removeOperation={this.removeOperation} />);
              }else if(operation == "filter-products-includes"){
                      return (<IncludeProducts key={index} removeOperation={this.removeOperation} />);
              }else if(operation == "filter-products-excludes"){
                      return (<ExcludeProducts key={index} removeOperation={this.removeOperation} />);
              }
        });

       return (
           <table>
             <tbody>
              {fields}
             </tbody>
           </table>
       );
    },
    render:function(){
        return (
          <div>
            <select className="browser-default" ref="operationsDropDown" id="operations-drop-down">
              <option value="adjust-price-multiply"> Adjust Price (Multiply) </option>
              <option value="adjust-price-add"> Adjust Price (Add) </option>
              <option value="filter-products-includes"> Filter products (Includes) </option>
              <option value="filter-products-excludes"> Filter products excludes </option>
            </select>
            <button onClick={this.addOperation} > Add Operation </button>
            <div id="adjust-import-data-rows">
                 {this.renderAdjustmentRows()}
            </div>
          </div>
        );
    }
});

ReactDOM.render(<DynamicFields />,document.getElementById('container'));

The problem is you are not providing index to the removeOperation function. Before you send the index your components should have the index. So pass it using index props as follows:

renderAdjustmentRows:function(){

   fields = this.state.operations.map((operation,index) =>{
          if(operation == "adjust-price-multiply"){
                return (<PriceMultiply key={index} index={index} removeOperation={this.removeOperation} />);
          }else if(operation == "adjust-price-add"){
                 return (<PriceAdd key={index} index={index} removeOperation={this.removeOperation} />);
          }else if(operation == "filter-products-includes"){
                  return (<IncludeProducts key={index} index={index} removeOperation={this.removeOperation} />);
          }else if(operation == "filter-products-excludes"){
                  return (<ExcludeProducts key={index} index={index} removeOperation={this.removeOperation} />);
          }
    });

And send the index props from remove button click of each Dynamic component. For that replace all the remove buttons with

 <button className="btn btn-danger" onClick={this.props.removeOperation.bind(null, this.props.index)} > Remove </button>

And you'll get what you want.

Complete code is available at https://jsfiddle.net/KishoreBarik/f8h3c82m/

Probably because in this bit of code:

removeOperation:function(index){
  var operations = this.state.operations;
  operations.splice(index,1);
  this.setState({operations:operations});
},

You are directly mutating state, as follows:

var operations = this.state.operations; // operations now points to array in state
operations.splice(index,1);             // splice mutates operations directly
// effect of these 2 statements is the same as
this.state.operations.splice(index,1);

You need to make a COPY of the state array first.
If you change the first line to:

var operations = this.state.operations.slice();

You should be fine..

For the removal issue: removeOperation() has not been given the index but an object. When you call it, give it an the right index

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM