React.js - 重新渲染时输入失去焦点

2022-08-30 02:12:45

我只是写到文本输入,如果我调用,所以 React 重新渲染我的 UI。问题是文本输入总是失去焦点,因此我需要对每个字母:D再次聚焦。onChangesetState

var EditorContainer = React.createClass({

    componentDidMount: function () {
        $(this.getDOMNode()).slimScroll({height: this.props.height, distance: '4px', size: '8px'});
    },

    componentDidUpdate: function () {
        console.log("zde");
        $(this.getDOMNode()).slimScroll({destroy: true}).slimScroll({height: 'auto', distance: '4px', size: '8px'});
    },

    changeSelectedComponentName: function (e) {
        //this.props.editor.selectedComponent.name = $(e.target).val();
        this.props.editor.forceUpdate();
    },

    render: function () {

        var style = {
            height: this.props.height + 'px'
        };
        return (
            <div className="container" style={style}>
                <div className="row">
                    <div className="col-xs-6">
                    {this.props.selected ? <h3>{this.props.selected.name}</h3> : ''}
                    {this.props.selected ? <input type="text" value={this.props.selected.name} onChange={this.changeSelectedComponentName} /> : ''}
                    </div>
                    <div className="col-xs-6">
                        <ComponentTree editor={this.props.editor} components={this.props.components}/>
                    </div>
                </div>
            </div>
        );
    }

});

答案 1

在没有看到其余代码的情况下,这只是一个猜测。创建编辑器容器时,请为组件指定唯一键:

<EditorContainer key="editor1"/>

当重新渲染发生时,如果看到相同的键,这将告诉 React 不要破坏并重新生成视图,而是重用。然后,获得焦点的项目应保持焦点。


答案 2

我一次又一次地回到这里,最后总是找到解决我其他地方的方法。所以,我会在这里记录它,因为我知道我会再次忘记这一点!

在我的情况下失去焦点的原因是因为我正在重新渲染on状态更改。inputinput

越野车代码:

import React from 'react';
import styled from 'styled-components';

class SuperAwesomeComp extends React.Component {
  state = {
    email: ''
  };
  updateEmail = e => {
    e.preventDefault();
    this.setState({ email: e.target.value });
  };
  render() {
    const Container = styled.div``;
    const Input = styled.input``;
    return (
      <Container>
        <Input
          type="text"
          placeholder="Gimme your email!"
          onChange={this.updateEmail}
          value={this.state.email}
        />
      </Container>
    )
  }
}

所以,问题是我总是开始在一个地方编码所有内容以快速测试,然后将其全部分解为单独的模块。但是,在这里,此策略适得其反,因为更新输入更改触发器的状态会呈现功能,并且焦点会丢失。

修复很简单,从一开始就做模块化,换句话说,“将组件移出功能”Inputrender

固定代码

import React from 'react';
import styled from 'styled-components';

const Container = styled.div``;
const Input = styled.input``;

class SuperAwesomeComp extends React.Component {
  state = {
    email: ''
  };
  updateEmail = e => {
    e.preventDefault();
    this.setState({ email: e.target.value });
  };
  render() {
    return (
      <Container>
        <Input
          type="text"
          placeholder="Gimme your email!"
          onChange={this.updateEmail}
          value={this.state.email}
        />
      </Container>
    )
  }
}

参考解决方案:https://github.com/styled-components/styled-components/issues/540#issuecomment-283664947