(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 再次聚焦该元素。更新了您的示例代码。
最初你有 <div>
,里面有 input
。提交表单组件后需要显示两个 <div>
:一个用于错误,一个用于表单。但是要更新什么,要创建什么?没有 key
并且有 精确构造函数的两个元素 React 决定更新现有的错误消息(并删除表单)并创建一个新的表单将被渲染。
并且在此移动中它失去了对场的关注。所以这不是因为一般的重新渲染,而是因为 reconciliation 具体。
所以,是的,不错,key
通过建议 React 不要在 div
秒内混乱,而是为错误消息创建新消息来解决这个问题。如果您有不同的元素(例如,div
和... ul
),您将永远不会遇到这种情况。但提供 key
也是处理该问题的合法方法。乍一看可能有点混乱。
当焦点在输入框中时,按回车键提交表单。提交时,错误会导致将错误插入状态,从而导致重新呈现并创建一个新元素来显示错误。
{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 再次聚焦该元素。更新了您的示例代码。
最初你有 <div>
,里面有 input
。提交表单组件后需要显示两个 <div>
:一个用于错误,一个用于表单。但是要更新什么,要创建什么?没有 key
并且有 精确构造函数的两个元素 React 决定更新现有的错误消息(并删除表单)并创建一个新的表单将被渲染。
并且在此移动中它失去了对场的关注。所以这不是因为一般的重新渲染,而是因为 reconciliation 具体。
所以,是的,不错,key
通过建议 React 不要在 div
秒内混乱,而是为错误消息创建新消息来解决这个问题。如果您有不同的元素(例如,div
和... ul
),您将永远不会遇到这种情况。但提供 key
也是处理该问题的合法方法。乍一看可能有点混乱。