【问题标题】: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 编辑的问题,是的,我正在使用反应路由器。

标签: javascript reactjs


【解决方案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/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-29
    • 1970-01-01
    • 2022-01-24
    • 2018-12-12
    • 1970-01-01
    • 2019-10-15
    • 2019-11-18
    • 1970-01-01
    相关资源
    最近更新 更多