#reactjs #firebase #google-cloud-firestore
#reactjs #firebase #google-облако-firestore
Вопрос:
Пожалуйста, я пытаюсь вставить данные в свой firestore, а также хочу, чтобы данные, которые я сохранил, сразу же появлялись на моем экране после отправки. Проблема, с которой я сталкиваюсь в настоящее время, заключается в том, что после вставки данных в firestore мне приходится перезагружать компонент, прежде чем увидеть его на своем экране. Вот мой код ниже, что я делаю неправильно.
function CreateGroup({ currentUser }) {
const [name, setName] = useState("");
const [group, setGroup] = useState([]);
const handleChange = (e) => {
const { value, name } = e.target;
setName({
[name]: value,
});
};
const handleSubmit = async (e) => {
e.preventDefault();
createGroup(currentUser, name.name);
};
let id = currentUser ? currentUser.id : "";
useEffect(() => {
const fetchData = () => {
if (id) {
firestore
.collection("users")
.doc(id)
.collection("group")
.get()
.then(function (snapshot) {
snapshot.forEach(function (doc) {
// console.log(doc.id, " => ", doc.data());
setGroup({
id: doc.id,
...doc.data(),
});
});
});
}
};
fetchData();
}, [id]);
return (
<div>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="exampleInputTitle">Group Name</label>
<input
type="text"
className="form-control"
name="name"
id="name"
aria-describedby="TitleHelp"
onChange={handleChange}
/>
</div>
<button type="submit" className="btn btn-primary">
Add group{" "}
</button>
</form>
<div>
<div key={group.id}>
{group.name} {group.admin}
</div>
</div>
</div>
);
}
Ответ №1:
Я бы сказал, создать локальное состояние, скажем
const [submited, setSubmited] = useState(true);
затем при отправке измените состояние на true, и в вашем useEffect используйте состояние «отправлено» также как зависимость вместе с идентификатором. OnHandleChange установил для «отправлено» значение false, чтобы мы могли отправить снова.
if (id) {}
становится
if (id amp;amp; submitted) {}
в результате использования.
function CreateGroup({ currentUser }) {
const [name, setName] = useState("");
const [group, setGroup] = useState([]);
const [submited, setSubmited] = useState(true);
const handleChange = (e) => {
const { value, name } = e.target;
setName({
[name]: value,
});
setSubmited(false);
};
const handleSubmit = async (e) => {
e.preventDefault();
createGroup(currentUser, name.name);
setSubmited(true);
};
let id = currentUser ? currentUser.id : "";
useEffect(() => {
const fetchData = () => {
if (id amp;amp; submitted) {
firestore
.collection("users")
.doc(id)
.collection("group")
.get()
.then(function (snapshot) {
snapshot.forEach(function (doc) {
// console.log(doc.id, " => ", doc.data());
setGroup({
id: doc.id,
...doc.data(),
});
});
});
}
};
fetchData();
}, [id, submitted]);
return (
<div>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="exampleInputTitle">Group Name</label>
<input
type="text"
className="form-control"
name="name"
id="name"
aria-describedby="TitleHelp"
onChange={handleChange}
/>
</div>
<button type="submit" className="btn btn-primary">
Add group{" "}
</button>
</form>
<div>
<div key={group.id}>
{group.name} {group.admin}
</div>
</div>
</div>
);
}
Ответ №2:
Да, вы можете добиться этого, сначала проверив, получает ли firestore только: -получение данных после отправки -успешный ответ
первый сценарий, который вы будете использовать.затем взять отправленные данные и установить их в ваше локальное состояние.
второй сценарий заключается в добавлении другого флага к вашему useeffect всякий раз, когда вы получаете успешный ответ от firestore
const handleSubmit = async (e) => {
e.preventDefault();
/*
*if this method is async you can use .then
*/
await createGroup(currentUser, name.name)
.then(res=>
//here you can set a state to trigger useeffect
)
};
useEffect(() => {
const fetchData = () => {
if (id) {
firestore
.collection("users")
.doc(id)
.collection("group")
.get()
.then(function (snapshot) {
snapshot.forEach(function (doc) {
// console.log(doc.id, " => ", doc.data());
setGroup({
id: doc.id,
...doc.data(),
});
});
});
}
};
//no need for this
fetchData();
}, [id,yourstateaftersubmit]);