简体   繁体   中英

how to add new input field after click plus icon in React Js

I'd like to add a new input everytime the plus icon is clicked but instead it always adds it to the end. I want it to be added next to the item that was clicked.

Here is the React code that I've used.

 const Input = props => ( <div className="answer-choice"> <input type="text" className="form-control" name={props.index} /> <div className="answer-choice-action"> <i onClick={props.addInput}>add</i> <i>Remove</i> </div> </div> ); class TodoApp extends React.Component { constructor(props) { super(props); this.state = { choices: [Input] }; } addInput = index => { this.setState(prevState => ({ choices: update(prevState.choices, { $splice: [[index, 0, Input]] }) })); }; render() { return ( <div> {this.state.choices.map((Element, index) => { return ( <Element key={index} addInput={() => { this.addInput(index); }} index={index} /> ); })} </div> ); } } ReactDOM.render(<TodoApp />, document.querySelector("#app")); 
 <div id="app"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 

I must admit this get me stuck for a while but there was a problem with how react deals with key props. When you use an index as a key it doesn't work. But if you make sure inputs will always be assigned the same key even when the list changes it will work as expected:

const Input = props => (
  <div className="answer-choice">
    <input type="text" className="form-control" name={props.index} />
    <div className="answer-choice-action">
      <i onClick={props.addInput}>add </i>
      <i>Remove</i>
    </div>
  </div>
);

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      choices: [],
      nrOfElements: 0
    };
  }

  addInput = index => {
    this.setState(prevState => {
      const choicesCopy = [...prevState.choices];
      choicesCopy.splice(index, 0, `input_${prevState.nrOfElements}`);
      return {
        choices: choicesCopy,
        nrOfElements: prevState.nrOfElements + 1
      };
    });
  };

  componentDidMount() {
    this.addInput(0);
  }

  render() {
    return (
      <div>
        {this.state.choices.map((name, index) => {
          return (
            <Input
              key={name}
              addInput={() => {
                this.addInput(index);
              }}
              index={index}
            />
          );
        })}
      </div>
    );
  }
}

Some reference from the docs :

Keys should be given to the elements inside the array to give the elements a stable identity ... ... We don't recommend using indexes for keys if the order of items may change . This can negatively impact performance and may cause issues with component state.

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