Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

140
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda