(p)React 避免在提交时不必要的重新渲染

Posted

技术标签:

【中文标题】(p)React 避免在提交时不必要的重新渲染【英文标题】:(p)React avoid unnecessary rerender on submit 【发布时间】:2020-01-10 13:50:33 【问题描述】:

当焦点在输入框中时,按回车键提交表单。在提交时,错误会导致将错误插入到状态中,从而导致重新渲染并创建一个新元素来显示错误。

error && <div>error</div>

这会重新渲染整个不必要的组件。

肯定 (p)react 应该能够检测到只有新的错误元素被插入,而 DOM 的其余部分可以保持不变?

这样做的结果是我失去了输入的焦点,而且条纹 iframe 被重新安装。我怎样才能防止这种情况发生

DEMO

export default class App extends Component 
  state =  val: "Sample input", error: null ;
  onSubmit = e => 
    e.preventDefault();
    this.setState( error: "Some error" );
  ;

  render(props,  val, error ) 
    return (
      <div>
        <h1>Example</h1>
        <form onSubmit=this.onSubmit>
          error && <div>error</div>
          <div class="list">
            <input
              value=val
              onChange=e => this.setState( val: e.target.value )
            />
            <button type="submit">Submit</button>
          </div>
        </form>
      </div>
    );
  


⭐️更新

问题是how react reconciles children。

解决方案 1 我可以通过向条件组件添加 key 属性来避免重新渲染整个组件并保持焦点。

error && <div key='formError'>error</div>

解决方案 2 或者,我可以将条件错误移到输入下方

<div class="list">
  <input
    value=val
    onChange=e => this.setState( val: e.target.value )
  />
  <button type="submit">Submit</button>
</div>
error && <div>error</div>

解决方案3或者使用一个类来隐藏错误

<div className=error ? 'error' : 'hide'>error</div>

【问题讨论】:

你也没有从一开始就专注。你需要使用 refs 来做到这一点。 【参考方案1】:

您无法避免重新渲染,因为设置状态或道具更改将再次渲染组件。您可以使用 ref 再次聚焦元素。更新了您的示例代码。

Demo Link

【讨论】:

【参考方案2】:

最初你有&lt;div&gt;,里面有input。提交表单组件后需要显示两个&lt;div&gt;:一个代表错误,一个代表表单。但是要更新什么,要创建什么?如果没有 key 并且有 两个精确构造函数的元素,React 决定使用错误消息更新现有的(并删除表单)并创建一个将呈现表单的新元素。

在这个动作中,它失去了在场内的焦点。所以这不是因为一般的重新渲染,而是因为reconciliation 特别是。

是的,不错,key 通过建议 React 不要在divs 中搞乱,而是为错误消息创建新的来解决这个问题。如果您有不同的元素(例如,div 和...ul),您将永远不会体验到这一点。但提供key 也是处理该问题的合法方式。乍一看可能有点混乱。

【讨论】:

明白了,相同的标签让 React 搞砸了要更新什么和创建什么。 正确,是对账算法。另一个解决方法是将错误 div 移到输入下方

以上是关于(p)React 避免在提交时不必要的重新渲染的主要内容,如果未能解决你的问题,请参考以下文章

使用重新选择计算派生状态时如何避免 React 重新渲染

在 React 中重新渲染条件渲染组件

避免在 React 中由对象字面量引起的重新渲染:如何处理对象中的变量?

React Context API 并避免重新渲染

React 重新渲染指南

在 React 中提升状态不会导致不必要的重新渲染吗?