ReactJS 组件文本区域未在状态更改时更新

ReactJS component textarea not updating on state change

我正在尝试编写笔记 taking/organizing 应用程序,但 运行 遇到了一个令人沮丧的错误。

这是我的组件:

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;

就目前而言,每当我在笔记之间切换并使用 note.body 道具中的新内容重新渲染笔记组件时,textarea 不会更改并保留前一个笔记的内容。我已经尝试对文本区域使用 value 属性而不是 defaultValue 属性,这确实解决了组件重新呈现时文本区域内容不更改的问题,但是当我这样做时,我不再能够在 textarea 字段中键入更新笔记

有没有人知道我既可以允许用户在文本字段中键入以更新注释,又可以在呈现不同注释时更改文本区域内容的方法?

谢谢

问题在于,将值设置为您的 prop 会导致组件的所有 re-renders 使用相同的 prop,因此新文本会被删除。一种解决方案是将文本保留在组件的本地状态中。要同时收听道具变化,您可以在收到新道具时设置状态。

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/

如果您使用的是 redux,您还可以对输入的更改事件触发操作以触发 re-render。您可以在减速器中保留输入值。

因为 componentWillReceiveProps 现在不安全 Max Sindwani 的回答现在有点过时了。

试试这些步骤:

  • 将您的组件转换为 class
  • 现在您可以包含 shouldComponentUpdate() 生命周期钩子
  • 创建您的事件处理程序并将其传递给 onChange
  • <textarea> 中,您可以将 defaultValue 属性换成 value(只需在处理程序中使用 event.preventDefault(),以便用户可以如果需要继续更新文本)

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