【问题标题】:react focus lose on contenteditable反应焦点失去内容可编辑
【发布时间】:2019-05-15 08:10:23
【问题描述】:

我写了一个自定义的内容可编辑组件,如下所示

export default class TextEditor extends React.Component {


constructor(props) {
    super(props);
    this.ref = React.createRef();
}


onChange = (e) => {
    let value = e.target.innerHTML;
    this.props.onChange(value);
}

render() {
    const { enabled , onChange , style, className, value } = this.props;
    return (
        <div>
            <div contentEditable={enabled}
                dangerouslySetInnerHTML={{ __html: value }} 
                ref={this.ref}
                onInput={this.onChange}
                style={{
                    ...style,
                    height: '80px',
                    overflow: 'auto',
                    cursor: enabled ? 'text' : 'inherit',
                }}
                className={`form-control form-control-sm ${className}`}
                placeholder="Optional Notes..."
            />
        </div>
    )
}
}

每当我在可编辑内容上键入内容时,光标都会移动到可编辑区域的开头。 这是因为 this.props.onChange(value);更新外部的值并发生重新渲染。如何防止重新渲染时光标重置??

【问题讨论】:

    标签: reactjs contenteditable


    【解决方案1】:

    您将需要 componentDidMountshouldComponentUpdate 的组合,如下所示:

    class TextEditor extends React.Component {
    
    
      constructor(props) {
          super(props);
          this.ref = React.createRef();
          this.onChange = this.onChange.bind(this);
      }
      
      
      onChange(){
            var html = this.ref.current.innerHTML;
            if (this.props.onChange && html !== this.lastHtml) {
                this.props.onChange({value: html});
            }
            this.lastHtml = html;
        }
        
        shouldComponentUpdate(nextProps){
            return nextProps.value !== this.ref.current.innerHTML;
        }
        
         componentDidUpdate() {
            if ( this.props.value !== this.ref.current.innerHTML ) {
               this.ref.current.innerHTML = this.props.value;
            }
        }
      
      render() {
          const { enabled , style, className, value } = this.props;
          return (
              <div>
                  <div contentEditable={enabled}
                      dangerouslySetInnerHTML={{ __html: value }} 
                      ref={this.ref}
                      onInput={this.onChange}
                      onBlur={this.onChange}
                      className="editable"
                      placeholder="Optional Notes..."
                  />
              </div>
          )
      }
      }
      
    class App extends React.Component { 
    
          constructor(props) {
          super(props);
          this.onChange = this.onChange.bind(this);
          this.state = {value: ""};
      }
      
       onChange({value}) {
          this.setState({value})
       }
      
      render(){
        return (
          <TextEditor enabled={true} onChange={this.onChange} value={this.state.value}/ >
        )
      }
     }
    
    ReactDOM.render( <App/> , document.getElementById('app'));
    .editable {
      width: 100%;
      height: 100px;
      border: 1px solid black;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    
    <div id="app"></div>

    【讨论】:

      猜你喜欢
      • 2013-07-02
      • 1970-01-01
      • 2015-07-21
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多