React官方文档中的一道挑战题:
https://zh-hans.react.dev/learn/you-might-not-need-an-effect#...
官方答案是提取出一个EditForm组件,为其加上key
import { useState, useEffect } from 'react';
export default function EditContact({ savedContact, onSave }) {
return (
<EditForm
savedContact={savedContact}
onSave={onSave}
key={savedContact.id}
></EditForm>
)
}
function EditForm({ savedContact, onSave }) {
const [name, setName] = useState(savedContact.name);
const [email, setEmail] = useState(savedContact.email);
return (
<section>
<label>
姓名:{' '}
<input
type="text"
value={name}
onChange={e => setName(e.target.value)}
/>
</label>
<label>
邮箱:{' '}
<input
type="email"
value={email}
onChange={e => setEmail(e.target.value)}
/>
</label>
<button onClick={() => {
const updatedData = {
id: savedContact.id,
name: name,
email: email
};
onSave(updatedData);
}}>
保存
</button>
<button onClick={() => {
setName(savedContact.name);
setEmail(savedContact.email);
}}>
重置
</button>
</section>
);
}我想知道,为什么不能直接在组件内的<section>上加key?
import { useState, useEffect } from 'react';
export default function EditContact({ savedContact, onSave }) {
const [name, setName] = useState(savedContact.name);
const [email, setEmail] = useState(savedContact.email);
return (
<section key={savedContact.id}>
<label>
姓名:{' '}
<input
type="text"
value={name}
onChange={e => setName(e.target.value)}
/>
</label>
<label>
邮箱:{' '}
<input
type="email"
value={email}
onChange={e => setEmail(e.target.value)}
/>
</label>
<button onClick={() => {
const updatedData = {
id: savedContact.id,
name: name,
email: email
};
onSave(updatedData);
}}>
保存
</button>
<button onClick={() => {
setName(savedContact.name);
setEmail(savedContact.email);
}}>
重置
</button>
</section>
);
}
我是新手,刚学React,我用过Vue。我无法理解这里的做法。
当
key不一样代表这是一个"新"的组件实例,它会重新创建,也就是重新经历vue中的created->mounted的过程即重新初始化实例,那么EditForm上持有的那些state(name/email)就会重置,而如果你key绑在section上那EditForm就不会重置自身的state,这一点在vue中也是一样的,你更改组件的key,那么组件上原先内部修改的那些data都会被重置掉