从Firestore集合中填充数据。

huangapple go评论62阅读模式
英文:

Populate data from firestore collection

问题

你遇到的问题是数据没有显示在表单上,尽管你已经设置了输入框的值。可能的原因之一是在以下代码块中:

// For updating userInput
useEffect(() => {
  // This runs when there's an ID and Data
  if (id) {
    setUserInfo({ ...data[id] });
  } else {
    setUserInfo({ ...initialState });
  }

  return () => {
    setUserInfo({ ...initialState });
  }
}, [id, data])

请确保 data[id] 中包含了你希望显示在表单上的数据。你可以在控制台中添加一些 console.log 来调试,检查 datadata[id] 的内容是否如预期。

此外,确保 handleInput 函数正常工作并将输入框的值正确地存储在 userInfo 中。你也可以在控制台中添加一些日志以确保数据在输入时被正确地更新。

最后,确保表单的输入框和 value 属性正确绑定,例如:

<input
  id="regNo"
  name="regNo"
  type="text"
  required
  placeholder="enter client id"
  value={regNo || ""}
  onChange={handleInput}
/>

如果以上检查都正常,但问题仍然存在,那可能需要进一步检查你的 React 组件逻辑以确保数据流正确。

英文:

I've written the function to retrieve data from firestore collection, when I console log the list, I can see all the documents in the "users" collection, the issue I'm facing currently is that the data is not displaying on the form which I want to update... I've set the value for all the inputs to retrieve the data, yet it's not showing on the form but I can see all the documents in the "users" collection in my console log..

Here's the code:-

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const initialState = {
regNo: &quot;&quot;,
firstName: &quot;&quot;,
lastName: &quot;&quot;,
email: &quot;&quot;,
reffBy: &quot;&quot;,
phoneNumber: &quot;&quot;,
age: &quot;&quot;,
date: &quot;&quot;,
status: &quot;&quot;,
};
const New = ({title}) =&gt; {
const [file, setFile] = useState(&quot;&quot;);
const [data, setData] = useState({});
const [userInfo, setUserInfo] = useState(initialState);
const navigate = useNavigate();
//fetch the id for each doc in a collection
const {id} = useParams();
const { regNo, firstName, lastName, email, reffBy, phoneNumber,  age, date, status}= userInfo;
// fetch ID from the collection
useEffect(() =&gt;{
//This runs only when there&#39;s an ID
const unsub = onSnapshot(
collection(db, &quot;users&quot;),
(snapShot) =&gt; {
let list = [];
snapShot.docs.forEach((doc) =&gt; {
list.push({ id: doc.id, ...doc.data() });
});
setData(list);
console.log(list)
},
(error) =&gt; {
console.log(error);
}
);
return () =&gt; {
unsub();
};
}, [id]);
// For updating userInput
useEffect(()=&gt;{
// This runs when there&#39;s an ID and Data
if (id) {
setUserInfo({...data[id]});
} else {
setUserInfo({...initialState});
}
return () =&gt;{
setUserInfo({...initialState});
}
}, [id, data])
const handleInput = (e) =&gt; {
const {name, value} = e.target;
setUserInfo({...userInfo, [name]: value});
}
const handleAdd = async(e) =&gt; {
e.preventDefault();
await addDoc(collection(db, &quot;users&quot;), {
...userInfo,
timeStamp: serverTimestamp(),
});
navigate(&quot;/&quot;)
}
return (
&lt;div className=&#39;new&#39;&gt;
&lt;Sidebar/&gt;
&lt;div className=&quot;newContainer&quot;&gt;
&lt;Navbar/&gt;
&lt;div className=&quot;top&quot;&gt;
&lt;h1&gt; {title} &lt;/h1&gt;
&lt;/div&gt;
&lt;div className=&quot;bottom&quot;&gt;
&lt;div className=&quot;left&quot;&gt;
&lt;img src={file ? URL.createObjectURL(file): &quot;https://icon-library.com/images/no-image-icon/no-image-icon-0.jpg&quot;} alt=&#39;&#39;/&gt;
&lt;/div&gt;
&lt;div className=&quot;right&quot;&gt;
&lt;form onSubmit={handleAdd}&gt;
&lt;div className=&quot;formInput&quot;&gt;
&lt;label htmlFor=&quot;file&quot;&gt;
Image: &lt;DriveFolderUploadIcon className=&quot;icon&quot; /&gt;
&lt;/label&gt;
&lt;input
type=&quot;file&quot;
id=&quot;file&quot;
onChange={(e) =&gt; setFile(e.target.files[0])}
style={{ display: &quot;none&quot; }}
/&gt;
&lt;/div&gt;
&lt;div className=&quot;formInput&quot;&gt;
&lt;label&gt;ID&lt;/label&gt;
&lt;input 
id=&quot;regNo&quot;
name=&quot;regNo&quot;
type=&quot;text&quot; 
required
placeholder=&quot;enter client id&quot;
value={regNo || &quot;&quot;}
onChange={handleInput}
/&gt;
&lt;/div&gt;
&lt;div className=&quot;formInput&quot;&gt;
&lt;label&gt;First Name&lt;/label&gt;
&lt;input 
id=&quot;firstName&quot;
name=&quot;firstName&quot;
type=&quot;text&quot; 
required
placeholder=&quot;enter first name&quot;
value={firstName || &quot;&quot;}
onChange={handleInput}
/&gt;
&lt;/div&gt;
&lt;div className=&quot;formInput&quot;&gt;
&lt;label&gt;Last Name&lt;/label&gt;
&lt;input 
id=&quot;lastName&quot;
name=&quot;lastName&quot;
type=&quot;text&quot; 
required
placeholder=&quot;enter last name&quot;
value={lastName || &quot;&quot;}
onChange={handleInput}
/&gt;
&lt;/div&gt;
&lt;div className=&quot;formInput&quot;&gt;
&lt;label&gt;Email&lt;/label&gt;
&lt;input 
id=&quot;email&quot;
name=&quot;email&quot;
type=&quot;email&quot; 
required
placeholder=&quot;enter your email address&quot;
value={email || &quot;&quot;}
onChange={handleInput}
/&gt;
&lt;/div&gt;
&lt;div className=&quot;formInput&quot;&gt;
&lt;label&gt;Refferal&lt;/label&gt;
&lt;input 
id=&quot;reffBy&quot;
name=&quot;reffBy&quot;
type=&quot;text&quot; 
required
placeholder=&quot;enter your referral&quot;
value={reffBy || &quot;&quot;}
onChange={handleInput}
/&gt;
&lt;/div&gt;
&lt;div className=&quot;formInput&quot;&gt;
&lt;label&gt;Phone Number&lt;/label&gt;
&lt;input 
id=&quot;phoneNumber&quot;
name=&quot;phoneNumber&quot;
type=&quot;number&quot; 
required
placeholder=&quot;phone number&quot;
value={phoneNumber || &quot;&quot;}
onChange={handleInput}
/&gt;
&lt;/div&gt;
&lt;div className=&quot;formInput&quot;&gt;
&lt;label&gt;Age&lt;/label&gt;
&lt;input 
id=&quot;age&quot;
name=&quot;age&quot;
type=&quot;text&quot; 
required
placeholder=&quot;age&quot;
value={age || &quot;&quot;}
onChange={handleInput}
/&gt;
&lt;/div&gt;
&lt;div className=&quot;formInput&quot;&gt;
&lt;label&gt;Date&lt;/label&gt;
&lt;input 
id=&quot;date&quot;
name=&quot;date&quot;
type=&quot;date&quot; 
required
value={date || &quot;&quot;}
onChange={handleInput}
/&gt;
&lt;/div&gt;
&lt;div className=&quot;formInput&quot;&gt;
&lt;label&gt;Status&lt;/label&gt;
&lt;input 
id=&quot;status&quot;
name=&quot;status&quot;
type=&quot;text&quot; 
required
placeholder=&quot;status&quot;
value={status || &quot;&quot;}
onChange={handleInput}
/&gt;
&lt;/div&gt;
&lt;button
type=&quot;submit&quot;
&gt;
Send
&lt;/button&gt;
&lt;/form&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
)
}

<!-- end snippet -->

Please what exactly is the issue why I'm not see the data on the form?

答案1

得分: 1

你第二个useEffect()中的代码假设data已经有一个值。但如果第一个useEffect()的异步操作尚未完成(几乎肯定还没有),在第二个useEffect()运行之前,userInfo变量将不会得到任何数据。

调用setUserInfo()的尝试依赖于成功获取“users”集合的完成。那么为什么不简单地将对setUserInfo()的调用放在onSnapshot()的回调函数内呢?

顺便说一下:我不确定你是否需要查询整个“users”集合,是吗?你不只是需要具有id UID的用户的一个文档吗?

此外,我不喜欢在这一行中混合“状态变量”和“常规JS变量”:

const { regNo, firstName, lastName, email, reffBy, phoneNumber,  age, date, status}= userInfo;

而是考虑使用以下方法访问每个字段:

userInfo["regNo"]

或者

userInfo.regNo
英文:

The code in your second useEffect() is assuming that data already has a value. But if the first useEffect()'s asynchronous action has not completed (and it almost certainly won't have) before the second useEffect runs, you'll get no data into the userInfo variable.

Your attempt to call setUserInfo() is dependent on the successful completion of the fetching of the "users" collection. So why not simply put the call to setUserInfo() INSIDE the callback function of onSnapshot() ?

BTW: I'm not sure that you need to be querying all of the "users" collection, do you? Don't you just need the ONE document for the user with the UID of id ??

Also, I am not a fan of mixing "state variables" and "regular JS variables" as being done in the line:

const { regNo, firstName, lastName, email, reffBy, phoneNumber,  age, date, status}= userInfo;

Instead, consider accessing each field with:

userInfo[&quot;regNo&quot;]

or

userInfo.regNo

huangapple
  • 本文由 发表于 2023年5月22日 06:56:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76302255.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定