前言
在开发时,我们复用一个组件,比如说切换不同的聊天窗口,这个窗口是公用的组件 <Chat/> 聊天窗口、 <ContactList/> 组件,控制不同人的 id 去切换不同的窗口和一个父组件 <Messenger/> ,
<Chat/> 包含的state值: text 。
import { useState } from 'react'; export default function Chat({ contact }) { const [text, setText] = useState(''); return ( <section className="chat"> <textarea value={text} placeholder={'Chat to ' + contact.name} onChange={e => setText(e.target.value)} /> <br /> <button>Send to {contact.email}</button> </section> ); }
<ContactList/> 触发 setTo 改变To的值。
export default function ContactList({ selectedContact, contacts, onSelect }) { return ( <section className="contact-list"> <ul> {contacts.map(contact => <li key={contact.id}> <button onClick={() => { // 调用setTo改变To的值 onSelect(contact); }}> {contact.name} </button> </li> )} </ul> </section> ); }
<Messenger/> 管理state值: To 。
当我们在侧边栏切换不同的 tab 的时候,里面输入的内容没有重置。
因为组件的JSX位置不变,且state是独立的,每次传递新的props值 to ,即使会重新渲染,但并不会改变子组件已有的state值。
之前我的解决方法:
有没有更好的解决方法?答案是有的,这就涉及到了子组件state的重置与保留。
一、state保留
当在父组件中引入一个子组件,就会在对应的 UI tree 上分配到一个位置,如果这个 UI tree 的位置一直没有被修改,那么它的state值也就不会发生改变。
这种说白了,只是props值改变,子组件state依旧保留。因为组件并没有从触发 (存在-->消失-->出现) 的情况。
二、state重置
如果要让上面的组件里 state 重置,就需要在其中一个组件套着任意标签,组件将会出 (存在-->消失-->出现) 的情况。
单击复选框时,计数器状态将重置。虽然呈现了Counter,但该div的第一个子元素从div变为section。section从DOM中移除时,它下面的整个树(包括Counter和它的状态)也会被销毁。
添加 key 值是最佳重置子组件 state 的解决方案。
优化前
优化后
总结
只要相同的组件呈现在相同的 UI tree 位置,React 就会保留 state 。 state 不保存在JSX标记中。它与放置JSX的树位置相关联。 您可以通过给子树一个不同的 key 来强制它重置状态。以上就是React 保留和重置State的详细内容,更多关于React 保留重置State的资料请关注其它相关文章!
查看更多关于React 保留和重置State的详细内容...