最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React.js: AddRemove input field on click of a button - Stack Overflow

programmeradmin1浏览0评论

React.js: Add/Remove input field on click of a button:

When a user click Add, I want a new input field to be added.

The name property is changing for every input, by increment the number in the middle:

document-0-document document-1-document

I receive the following error:

"TypeError: this is undefined var arr = this.state.documents;"

I have an idea what is creating the error but I didn't found a fix.

HTML Code.

<fieldset class="fieldset">
  <input type="file" name="document-0-document">
  <div class="more-documents">
    <input type="file" name="document-1-document">
    <button data-reactid=".0.1">Add</button>
  </div>
 </fieldset>

Main Component code:

class DocumentsFieldSet extends Component{

  constructor(props){
      super(props);
      this.state = {documents:[]}
  }

  add(i) {
      var arr  = this.state.documents;
      arr.push(i);
      this.setState({documents: arr});
  }

  eachDocument () {
      return <DocumentInput key={i}/>
  }

  render (){
      return (
        <div>
            {this.state.documents.map(this.eachDocument)}
            <button onClick={this.add.bind()}>Add</button>
        </div>
      )
  }
}

ReactDOM.render(<DocumentsFieldSet/>, document.querySelector ('.more-    documents'))

Component Code

class DocumentInput extends Component {
  render() {
      return <input type="file" name="document-{i}-document" ref="" />;
  }
}

export default DocumentInput;

React.js: Add/Remove input field on click of a button:

When a user click Add, I want a new input field to be added.

The name property is changing for every input, by increment the number in the middle:

document-0-document document-1-document

I receive the following error:

"TypeError: this is undefined var arr = this.state.documents;"

I have an idea what is creating the error but I didn't found a fix.

HTML Code.

<fieldset class="fieldset">
  <input type="file" name="document-0-document">
  <div class="more-documents">
    <input type="file" name="document-1-document">
    <button data-reactid=".0.1">Add</button>
  </div>
 </fieldset>

Main Component code:

class DocumentsFieldSet extends Component{

  constructor(props){
      super(props);
      this.state = {documents:[]}
  }

  add(i) {
      var arr  = this.state.documents;
      arr.push(i);
      this.setState({documents: arr});
  }

  eachDocument () {
      return <DocumentInput key={i}/>
  }

  render (){
      return (
        <div>
            {this.state.documents.map(this.eachDocument)}
            <button onClick={this.add.bind()}>Add</button>
        </div>
      )
  }
}

ReactDOM.render(<DocumentsFieldSet/>, document.querySelector ('.more-    documents'))

Component Code

class DocumentInput extends Component {
  render() {
      return <input type="file" name="document-{i}-document" ref="" />;
  }
}

export default DocumentInput;
Share Improve this question edited Jan 4, 2018 at 3:15 grantnz 7,4231 gold badge32 silver badges38 bronze badges asked Jul 26, 2016 at 12:59 user3541631user3541631 4,00811 gold badges54 silver badges123 bronze badges 1
  • What you want to add? – Alessander Franca Commented Jul 26, 2016 at 13:05
Add a comment  | 

3 Answers 3

Reset to default 13

You have several mistakes in your example

  1. You need bind this for .add method

  2. You don't put to this.state.documents array index

  3. Inside DocumentInput there is no i variable

class DocumentInput extends React.Component {
  render() {
    return <input 
      type="file" 
      name={ `document-${ this.props.index }-document` } 
    />;
  }
}

class DocumentsFieldSet extends React.Component{
  constructor(props){
    super(props);

    this.state = { 
      documents: []
    }
    
    this.add = this.add.bind(this);
  }

  add() {
    const documents = this.state.documents.concat(DocumentInput);
    this.setState({ documents });
  }
  
  render () {
    const documents = this.state.documents.map((Element, index) => {
      return <Element key={ index } index={ index } />
    });

    return <div>
      <button onClick={ this.add }>Add</button>
    
      <div className="inputs">
        { documents }
      </div>
    </div>
  }
}

ReactDOM.render(
  <DocumentsFieldSet />,
  document.getElementById('container')
);
.inputs {
  margin: 5px 0;
  padding: 10px;
  border: 2px solid #000;
}
<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>
<div id="container"></div>

Maybe you forgot to pass context into bind function.

replace

<button onClick={this.add.bind()}>Add</button>

to

<button onClick={this.add.bind(this)}>Add</button>

Write your add function as an arrow function. It would bind function to this for you. Read more about it here

add = (i) => {
    var arr = this.state.documents;
    arr.push(i);
    this.setState({documents: arr});
};

Also I would rewrite your function to be:

add = (i) => {
    const { documents } = this.state;
    documents.push(i);
    this.setState({ documents });
};
发布评论

评论列表(0)

  1. 暂无评论