(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】:最初你有<div>
,里面有input
。提交表单组件后需要显示两个<div>
:一个代表错误,一个代表表单。但是要更新什么,要创建什么?如果没有 key
并且有 两个精确构造函数的元素,React 决定使用错误消息更新现有的(并删除表单)并创建一个将呈现表单的新元素。
在这个动作中,它失去了在场内的焦点。所以这不是因为一般的重新渲染,而是因为reconciliation 特别是。
是的,不错,key
通过建议 React 不要在div
s 中搞乱,而是为错误消息创建新的来解决这个问题。如果您有不同的元素(例如,div
和...ul
),您将永远不会体验到这一点。但提供key
也是处理该问题的合法方式。乍一看可能有点混乱。
【讨论】:
明白了,相同的标签让 React 搞砸了要更新什么和创建什么。 正确,是对账算法。另一个解决方法是将错误 div 移到输入下方以上是关于(p)React 避免在提交时不必要的重新渲染的主要内容,如果未能解决你的问题,请参考以下文章