Search code examples
javascriptreactjsmeteormeteor-react

Dynamically assigning the ref to textarea, but it's returning the last field value.


As stated in title, Only the last form of the array returned value. Other form returned empty. Need help understanding how:

addComment(event) {
    event.preventDefault();

    const commentContent = this.refs.commentContent.value;

    console.log(commentContent);
    this.refs.commentContent.value = '';

}

renderArticleList() {
   return (
       this.props.articles.map( (article) => {
          const articleId = article._id;
          return (
             <div key={articleId}>

                <form onSubmit={this.addComment.bind(this)}>
                   <textarea ref="commentContent"/>
                   <button type="submit">Add Comment</button>
                </form>

             </div>
          )
       })
    )
 }

Code Solutions to solve problem greatly appreciated. Links to help understand and solve the problem also great.


Solution

  • Reason is, you are using the same ref for all the input element, to make the ref unique, append the index of form with the ref, and pass that index to submit function, and use that index to access the input field value, Try this:

    class App extends React.Component {
    
        constructor(props) {
            super(props);
            this.state = {
                value: ''
            };
        }
    
        addComment(i, event) {
           event.preventDefault();
           let ref = 'commentContent'+i;
           console.log('value', this.refs[ref].value);
        }
    
        render() {
            return (
              <div>
                {
                  this.props.articles.map( (article,i) => {
                      const articleId = article._id;
                      return (
                        <div key={articleId}>
    
                          <form onSubmit={this.addComment.bind(this,i)}>
                            <textarea ref={"commentContent"+i}/>
                            <button type="submit">Add Comment</button>
                          </form>
    
                        </div>
                      )
                    })
                }
              </div>
            )
        }
    }
    
    
    ReactDOM.render(<App />, document.getElementById('container'));
    

    Check the working code:

    class App extends React.Component {
    
    constructor(props) {
        super(props);
        this.state = {
            value: ''
        };
    }
    
    addComment(i, event) {
    event.preventDefault();
    let ref = 'commentContent'+i;
    console.log('value', this.refs[ref].value);
    }
    
    render() {
    return (<div>
      {[1,2,3].map( (article,i) => {
        return (
          <div key={i}>
            <form onSubmit={this.addComment.bind(this,i)}>
              <textarea ref={"commentContent"+i}/>
              <button type="submit">Add Comment</button>
            </form>
          </div>
        )
      })}
      </div>
      )
      }
    
    }
    
    ReactDOM.render(<App />, document.getElementById('container'));
    <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'/>

    Check the working fiddle: https://jsfiddle.net/0fggkdw3/