反应输入文本失去对重新渲染的关注

Posted

技术标签:

【中文标题】反应输入文本失去对重新渲染的关注【英文标题】:React input text losing focus on rerender 【发布时间】:2018-07-05 22:52:14 【问题描述】:

我正在使用 react 并且想要一个显示内存数据存储中的值的输入文本,然后在值更改时更新存储,这会触发重新渲染。我看到的问题是我的输入文本失去了对重新渲染的关注。我尝试设置 key 属性并覆盖 shouldComponentUpdate 并返回 false 以防止 react 重新渲染组件,但无济于事。似乎后者无论如何都不是一个好的长期解决方案。

来自文档:

请注意,未来 React 可能会将 shouldComponentUpdate() 视为提示而不是严格指令,返回 false 仍可能导致组件重新渲染。

代码:

export class TextInput extends React.Component 
  constructor(props) 
    super();
    this.storePath = props.value;
    const value = dataStore.get(this.storePath) || '';
    this.state =  value ;
  

  shouldComponentUpdate()  return false; 

  update(event) 
    dataStore.update(this.storePath, event.target.value);
  

  render() 
    return <input type="text" value=this.state.value onChange=e => this.update(e)/>;
  

编辑

我正在使用反应路由器。

const App = props => (
  <Router history=browserHistory>
    <div>
      <Switch>
        Array.from(this.routeMap.keys()).map(path => 
          const viewFn = this.routeMap.get(path);
          return <Route key=path path=path render=viewFn></Route>;
        )
      </Switch>
    </div>
  </Router>
);

有一个通过路由拉入的***组件,它正在使用我的 TextInput 组件。

【问题讨论】:

你在使用 React 路由器吗?这不应该在重新渲染时发生,除非 createElement 被调用 是否有父组件在更新时重新渲染?这个组件可能会在每次更新时卸载吗? (通过登录componentWillUnmount 进行验证)。 您是否尝试为您的输入设置 ref 并将焦点更新到 componentDidUpdate ?还是使用 autoFocus ?还是&lt;input ref=input =&gt; input &amp;&amp; input.focus()/&gt; 如果你使用 react 路由器:reacttraining.com/react-router/web/api/Route/component 如果你不是那么我会使用 refs 作为条带化推荐 @RobbieMilejczak 编辑的问题,是的,我正在使用反应路由器。 【参考方案1】:

我找到了。每次我调用ReactDOM.render 时,我都在重新声明我的***组件函数,这似乎导致我的输入文本失去焦点。它必须对传递的组件函数/类进行身份检查,以查看它是否与前一个相同,如果不是,则从头开始完全重新渲染。

所以,以下是的方法:

const render = props => 
  const App = props => (
    <Router history=browserHistory>
      <Switch>
        <Route key="/login" path="/login" render=() => View(props)/>
      </Switch>
    </Router>
  );
  ReactDOM.render(
    <App ...props/>,
    rootDiv
  );


render();
render();

这里的 jsfiddle 失败:https://jsfiddle.net/chwsmchd/

这是正确的做法:

const App = props => (
  <Router history=browserHistory>
    <Switch>
      <Route key="/login" path="/login" render=() => View(props)/>
    </Switch>
  </Router>
);

const render = props => 
  ReactDOM.render(
    <App ...props/>,
    rootDiv
  );


render();
render();

正确的 jsfiddle:https://jsfiddle.net/gzzpmpbz/

【讨论】:

以上是关于反应输入文本失去对重新渲染的关注的主要内容,如果未能解决你的问题,请参考以下文章

当状态改变时,对文本字段做出反应 onChange 更新整个组件

输入字段失去对每个字符类型的关注 - 反应

在重新渲染时反应不更新属性

即使道具没有改变,为啥还要对重新渲染组件做出反应?

对道具更改做出反应重新渲染

重新渲染后哪个组件需要键来保持焦点?