Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

142
Views
ReactJS component textarea not updating on state change

I'm trying to write a note taking/organizing app and I've run into a frustrating bug.

Here's my component:

import React from 'react';

const Note = (props) => {
  let textarea, noteForm;
  if (props.note) {
    return (
      <div>
        <button onClick={() => {
          props.handleUpdateClick(props.selectedFolderId, props.selectedNoteId, textarea.value);
        }}>
          Update
        </button>
        <textarea
          defaultValue={props.note.body}
          ref={node => {textarea = node;}}
        />
      </div>
    );
  } else {
    return <div></div>;
  }
};

export default Note;

As it currently stands, whenever I switch between notes and rerender the note component with new content from the note.body prop, the textarea does not change and retains the content from the previous note. I've tried using the value attribute instead of the defaultValue attribute for the text area which doe fix the problem of the text area content not changing when the component rerenders, but when I do that I'm longer able to type in the textarea field to update the note

Doe anyone know a way I can both allow for users to type in the text field to update the note as well as have the textarea content change when I render different notes?

Thank you

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

The problem is that setting the value to your prop will cause all re-renders of the component to use the same prop, so new text is obliterated. One solution is to preserve the text in the local state of the component. To simultaneously listen to prop changes, you can set the state when you receive new props.

const Note = React.createClass({

  getInitialState() {
        return {
        text : this.props.note.body
    }
  },

  componentWillReceiveProps: function(nextProps) {
    if (typeof nextProps.note != 'undefined') {
        this.setState({text: nextProps.note.body });
    }
  },

  render() {
    if (this.props.note) {
      return (
        <div>
          <button onClick={(e) => {
            // Fire a callback that re-renders the parent.
            // render(this.textarea.value);
          }}>
            Update
          </button>
          <textarea
            onChange={e => this.setState({ text : e.target.value })}
            value={this.state.text}
            ref={node => {this.textarea = node;}}
          />
        </div>
      );
    } else {
      return <div></div>;
    }
  }
});

https://jsfiddle.net/69z2wepo/96238/

If you are using redux, you could also fire an action on the change event of the input to trigger a re-render. You could preserve the input value in a reducer.

over 4 years ago · Santiago Trujillo Report

0

Because componentWillReceiveProps is now unsafe Max Sindwani's answer is now a little out date.

Try these steps:

  • convert your component to a class
  • now you can include the shouldComponentUpdate() lifecycle hook
  • create your event handler and pass it into onChange
  • in <textarea> you can swap out defaultValue attribute for value (just use event.preventDefault() in the handler so that a user can continue to update text if required)

        import React from 'react';
    
        export class Note extends React.Component {
    
        constructor(props) {
            super(props);
            this.state={text: this.props.note.body}
        }
    
        shouldComponentUpdate(nextProps) {
            if(nextProps.note.body !== this.state.text) {
                this.setState({text: nextProps.note.body})
                return true;
            }
            return false;
        }
    
        updateText = (event) => {
            event.preventDefault();
            this.setState({text: nextProps.note.body});
        }
    
     render() {
       if (this.props.note) {
         return (
           <div>
             <textarea
               onChange={this.updateText}
               value={this.state.text}
               name={'display'} 
             />
           </div>
         );
      } else {
         return <div></div>;
       }
     }});
    
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!