ReactJS component textarea not updating on state change

穿精又带淫゛_ 提交于 2021-01-02 07:13:23

问题


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


回答1:


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.




回答2:


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>;
       }
     }});
    


来源:https://stackoverflow.com/questions/41775004/reactjs-component-textarea-not-updating-on-state-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!