javascript - 如何将从 useEffect 中获取的 initialValue 放在 textField 中?
问题描述
我有这个编辑页面,其中名字、姓氏和地址的初始值应该来自使用 useEffect 从 firebase firestore 检索到的数据。
useEffect(() => {
const unsubscribe = firestore
.collection("users")
.doc(uid)
.onSnapshot((snapshot) => {
const arr = [];
arr.push({
...snapshot.data(),
});
setUsers(arr);
});
return () => {
unsubscribe();
};
}, []);
handleSubmit 将更新的信息保存在 firestore 中:
const handleSubmit = async (e) => {
e.preventDefault();
try {
const userRef = firestore.collection("users").doc(uid);
const ref = userRef.set(
{
firstName,
middleName,
lastName,
address,
},
{ merge: true }
);
console.log(" saved");
} catch (err) {
console.log(err);
}
};
下面是整个代码:
const edit = () => {
const uid = location.state;
const [isLoading, setIsLoading] = useState(false);
const [users, setUsers] = useState([]);
const [firstName, setFirstName] = useState("");
useEffect(() => {
const unsubscribe = firestore
.collection("users")
.doc(uid)
.onSnapshot((snapshot) => {
const arr = [];
arr.push({
...snapshot.data(),
});
setUsers(arr);
setIsLoading(true);
});
return () => {
unsubscribe();
};
}, []);
const handleSubmit = (e) => {
e.preventDefault();
console.log(firstName);
};
return (
<div>
{isLoading ? (
<>
{users &&
users.map((user) => (
<li style={{ listStyle: "none" }}>
<CardHeader title="Update Profile" />
<form onSubmit={handleSubmit}>
<TextField
type="text"
value={user.firstName}
variant="outlined"
label="First Name"
fullWidth
onChange={(e) => setFirstName(e.target.value)}
/>
<Button type="submit"> Submit</Button>
</form>
</li>
))}
</>
) : (
<h1>Loading...</h1>
)}
</div>
);
};
export default edit;
假设我想编辑用户“John Park”的地址。这些文本字段应该具有 John 的名字和姓氏的初始值,因此即使地址字段是唯一更新的字段,当保存在 firestore 中时,名字和姓氏字段也不会是空字符串。我该怎么做?谢谢你。
解决方案
似乎您正在更新本地状态,但它没有初始化为空字符串。
您的更新应该是users
您获取的本地副本,并且提交处理程序应该获取特定用户以在您的后端进行更新。
const [users, setUsers] = React.useState([]);
更改处理程序 - 柯里化函数以获取索引并返回处理程序。它将前一个状态映射users
到下一个状态,更新指定索引处的用户。
const changeHandler = index => e => {
const { name, value } = e.target;
setUsers(users => users.map((user, i) => i === index
? {
...user,
[name]: value,
}
: user,
));
};
提交处理程序 - curried 函数以获取特定用户对象的索引以发送到后端。
const handleSubmit = index => async (e) => {
e.preventDefault();
try {
const userRef = firestore.collection("users").doc(uid);
const ref = userRef.set(
{ ...users[index] }, // <-- user by index
{ merge: true }
);
console.log(" saved");
} catch (err) {
console.log(err);
}
};
将当前映射的索引传递给处理程序。将属性添加name
到与输入的用户属性名称匹配的每个字段。
return (
<div>
{isLoading ? (
<>
{users &&
users.map((user, index) => (
<li style={{ listStyle: "none" }}>
<CardHeader title="Update Profile" />
<form onSubmit={handleSubmit(index)}> // <-- pass index
<TextField
type="text"
value={user.firstName}
variant="outlined"
label="First Name"
name="firstName" // <-- add name attribute
fullWidth
onChange={changeHandler(index)} // <-- pass index to handler
/>
... other fields
<Button type="submit">Submit</Button>
</form>
</li>
))}
</>
) : (
<h1>Loading...</h1>
)}
</div>
);
推荐阅读
- django - 如何在 django 中正确分配 through 属性?
- botframework - 如何获取组织中的 MS Teams 用户列表?
- r - 如果变量具有重复值,则从数据框中删除组
- python - 重定向到视图时的 Django NoReverseMatch
- javascript - 子字符串而不是子字符串的正则表达式
- joomla - 如何在 Joomla 中使用 Smart Slider 创建此滑块?
- php - Symfony 3.4:如何在树枝中获得完整的国家名称
- scala - Scala JavaConverters 似乎不适用于静态方法返回的集合
- ionic3 - InAppBrowser 与 ionic 3 应用程序中的 Admob Banner 重叠
- ms-office - Power BI / DAX - 变化时间段的动态比较