React.js-重新呈现时输入失去焦点

JavaScript

Mandy凯

2020-03-12

我只是在写文本输入,onChange如果我打电话setState,那么React会重新渲染我的UI。问题是文本输入始终会失去焦点,因此我需要再次针对每个字母:D。

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

});

第1340篇《React.js-重新呈现时输入失去焦点》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

12个回答
十三Mandy 2020.03.13

我遇到了这个问题,结果却是我正在使用功能组件并与父组件的状态链接。如果我改用类组件,问题就消失了。希望在使用功能组件时可以解决此问题,因为对于简单的项目渲染器等而言,它要方便得多。

小红酱 2020.03.13

我将value道具切换defaultValue这对我行得通。

...
// before
<input value={myVar} />

// after
<input defaultValue={myVar} />
神奇宝儿 2020.03.13

我的问题是我使用项目的值动态命名了密钥,在本例中为“名称”,因此密钥为key = { ${item.name}-${index}}。因此,当我想使用item.name作为值更改输入时,它们的键也将更改,因此react无法识别该元素

樱猪猪 2020.03.13

原来,我绑定this到了导致其重新渲染的组件。

我以为可以将其发布在这里,以防其他人遇到此问题。

我不得不改变

<Field
    label="Post Content"
    name="text"
    component={this.renderField.bind(this)}
/>

<Field
    label="Post Content"
    name="text"
    component={this.renderField}
/>

简单修复,因为在我的情况下,我实际上并不需要thisin renderField,但是希望我发布此内容会对其他人有所帮助。

樱神奇 2020.03.13

对我而言,这是由于在搜索结果列表相同的组件(称为UserList)中呈现了搜索输入框因此,每当搜索结果更改时,整个UserList组件都会重新呈现,包括输入框。

我的解决方案是创建一个名为UserListSearch的全新组件,该组件UserList分开我不需要在UserListSearch的输入字段上设置键即可工作。现在,我的UsersContainer的呈现函数如下所示:

class UserContainer extends React.Component {
  render() {
    return (
      <div>
        <Route
          exact
          path={this.props.match.url}
          render={() => (
            <div>
              <UserListSearch
                handleSearchChange={this.handleSearchChange}
                searchTerm={this.state.searchTerm}
              />
              <UserList
                isLoading={this.state.isLoading}
                users={this.props.users}
                user={this.state.user}
                handleNewUserClick={this.handleNewUserClick}
              />
            </div>
          )}
        />
      </div>  
    )
  }
}

希望这也会对某人有所帮助。

乐ASam 2020.03.13

提供的答案并没有帮助我,这是我所做的,但是我遇到的情况非常特殊。

为了清理代码,我倾向于使用这种格式,直到准备将组件拉入另一个文件为止。

render(){
   const MyInput = () => {
      return <input onChange={(e)=>this.setState({text: e.target.value}) />
   }
   return(
      <div>
         <MyInput />
      </div>
   )

但是,这导致它失去了焦点,当我将代码直接放在div中时它就起作用了。

return(
   <div>
      <input onChange={(e)=>this.setState({text: e.target.value}) />
   </div>
)

我不知道为什么会这样,这是我用这种方式编写时遇到的唯一问题,而且我会在大多数文件中都这样做,但是如果有人做类似的事情,这就是为什么它会失去焦点。

村村凯 2020.03.13

核心原因是:当React重新渲染时,您以前的DOM引用将无效。这意味着react已经改变了DOM树,您this.refs.input.focus将不起作用,因为这里的输入不再存在。

Tony米亚 2020.03.13

我刚遇到这个问题,来到这里寻求帮助。检查您的CSS!输入栏位无法输入,user-select: none;或在iPad上无法使用。

卡卡西路易前端 2020.03.13

在只有一个输入需要集中的情况下,autoFocus属性应用于input元素可以作为一种变通方法。在那种情况下,key属性将是不必要的,因为它只是一个元素,此外,您不必担心将input元素分解为自己的组件,以避免失去对重新渲染主组件的关注。

神无伽罗 2020.03.13

我的答案类似于@ z5h所说的。

就我而言,我曾经为组件Math.random()生成一个唯一key的。

我认为key只能用于触发该特定组件的重新呈现,而不是重新呈现该数组中的所有组件(我在代码中返回了一个组件数组)。我不知道它用于重新渲染后恢复状态。

删除那对我来说很有效。

PS:我本可以对此发表评论,但是对此我没有足够的声誉。

老丝逆天 2020.03.13

如果这是React Router内的问题,请<Route/>使用renderprop而不是component

<Route path="/user" render={() => <UserPage/>} />


失去焦点是因为component道具React.createElement每次都使用而不是仅重新渲染更改。

此处的详细信息:https : //reacttraining.com/react-router/web/api/Route/component

小小飞云 2020.03.13

没有看到其余的代码,这是一个猜测。创建EditorContainer时,请为组件指定一个唯一键:

<EditorContainer key="editor1"/>

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

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android