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

(p)React avoid unnecessary rerender on submit

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

{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或者使用class隐藏错误

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

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

Demo Link

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

并且在此移动中它失去了对场的关注。所以这不是因为一般的重新渲染,而是因为 reconciliation 具体。

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