React native React本机状态未通过React的useSate方法更新
我的代码中似乎有什么问题, 我正在创建一个基于firestore和firebase的应用程序。 到目前为止一切正常但现在我想添加一个唯一键,从1开始,然后按升序到firebase中的每个项目,通过它我可以检索平面列表组件中的所有项目。 但我不能这么做。 我目前面临的一个问题是,当用户填写表单并单击发布按钮**[发布按钮的详细信息如下]**数据存储在Firebase中,但计数器在第二次尝试后没有增加(意味着用户填写另一张表格并单击POST按钮)值最终递增 表示两个表单填充后,计数器增加一个,但我想在每个表单填充时增加计数器 请帮帮我 请参见下面的代码React native React本机状态未通过React的useSate方法更新,react-native,use-state,react-native-state,React Native,Use State,React Native State,我的代码中似乎有什么问题, 我正在创建一个基于firestore和firebase的应用程序。 到目前为止一切正常但现在我想添加一个唯一键,从1开始,然后按升序到firebase中的每个项目,通过它我可以检索平面列表组件中的所有项目。 但我不能这么做。 我目前面临的一个问题是,当用户填写表单并单击发布按钮**[发布按钮的详细信息如下]**数据存储在Firebase中,但计数器在第二次尝试后没有增加(意味着用户填写另一张表格并单击POST按钮)值最终递增 表示两个表单填充后,计数器增加一个,但我想
const [adTitle, setAdTitle] = useState('')
const [adDescription, setAdDescription] = useState('')
const [yearOfPurchase, setYearOfPurchase] = useState('')
const [price, setPrice] = useState('')
const [contactNo, setContactNo] = useState('')
const [image, setImage] = useState('')
const [counter, setCounter] = useState(0)
我在我的应用程序中使用了这些赌注。所有其他的工作都很好。问题就在这里
const [counter, setCounter] = useState(0)
当用户按下post按钮时调用此功能
const postData = async () => {
if (!adTitle || !adDescription || !yearOfPurchase || !price || !contactNo) {
Alert.alert("Please fill all the Fields")
return
}
try {
getCounter(); // <-- called this function for Counter, Details are Below
await fireStore().collection("ads").add({
adTitle,
adDescription,
yearOfPurchase,
price,
contactNo,
image,
uniqueID: counter,
uid: Auth().currentUser.uid
})
Alert.alert("Item Successfully Posted..")
setAdTitle('')
setAdDescription('')
setYearOfPurchase('')
setPrice('')
setContactNo('')
setImage('')
} catch (err) {
Alert.alert("Something went wrong\nPlease try again...")
}
}
我相信您的问题在于
setCounter
是异步运行的,并且没有返回您可以与async/await一起使用的承诺。在您的情况下,调用getCounter
,触发setCounter
函数,然后在setCounter
更新计数器的值
我能想到的最佳解决方案是使用useffect
,因为它可以用来监视计数器的值,然后在更新计数器时触发函数调用。因此,您可以执行以下操作:
const YourElement = () => {
const getCounter = async () => {
try {
const querySnap = await fireStore().collection('Counter').doc('count').get()
setCounter((querySnap.data().counter)+1)
} catch(error) {
alert("Something went wrong\n[Error]: "+ error)
}
try {
await fireStore().collection('Counter').doc("count").update({
counter: counter
})
} catch {
// alert("Something went wrong\nPlease try again...")
}
}
const postData = async () => {
if (!adTitle || !adDescription || !yearOfPurchase || !price || !contactNo) {
Alert.alert("Please fill all the Fields")
return
}
try {
getCounter()
Alert.alert("Item Successfully Posted..")
setAdTitle('')
setAdDescription('')
setYearOfPurchase('')
setPrice('')
setContactNo('')
setImage('')
} catch (err) {
Alert.alert("Something went wrong\nPlease try again...")
}
}
useEffect(()=>{
fireStore().collection("ads").add({
adTitle,
adDescription,
yearOfPurchase,
price,
contactNo,
image,
uniqueID: counter,
uid: Auth().currentUser.uid
})},[counter])
return <ChildElements/>
}
常量YourElement=()=>{
const getCounter=async()=>{
试一试{
const querySnap=wait fireStore().collection('Counter').doc('count').get()
setCounter((querySnap.data().counter)+1)
}捕获(错误){
警报(“出现问题\n[错误]:”+错误)
}
试一试{
等待fireStore().集合('Counter')。文档('count')。更新({
柜台:柜台
})
}抓住{
//警报(“出现问题\n请重试…”)
}
}
const postData=async()=>{
如果(!adTitle | | |!addDescription | |!购买年份| |!价格| |!联系人编号){
Alert.Alert(“请填写所有字段”)
返回
}
试一试{
getCounter()
Alert.Alert(“已成功发布的项目…”
setAdTitle(“”)
setAddDescription(“”)
setYearOfPurchase(“”)
设定价格(“”)
setContactNo(“”)
setImage(“”)
}捕捉(错误){
Alert.Alert(“出现问题\n请重试…”)
}
}
useffect(()=>{
fireStore().集合(“广告”).添加({
广告标题,
补充说明,
购买年份,
价格,
联系人号码:,
形象,,
唯一标识:计数器,
uid:Auth().currentUser.uid
})}[柜台])
返回
}
这样,数据只会在
计数器
更新后发送到firebase。我相信您的问题在于setCounter
是异步运行的,并且不会返回可以与async/await一起使用的承诺。在您的情况下,调用getCounter
会触发setCounter
函数然后在setCounter
更新计数器的值之前,将计数器发送到firebase
我能想到的最佳解决方案是使用useffect
,因为它可以用来监视计数器的值,然后在更新计数器时触发函数调用。因此,您可以执行以下操作:
const YourElement = () => {
const getCounter = async () => {
try {
const querySnap = await fireStore().collection('Counter').doc('count').get()
setCounter((querySnap.data().counter)+1)
} catch(error) {
alert("Something went wrong\n[Error]: "+ error)
}
try {
await fireStore().collection('Counter').doc("count").update({
counter: counter
})
} catch {
// alert("Something went wrong\nPlease try again...")
}
}
const postData = async () => {
if (!adTitle || !adDescription || !yearOfPurchase || !price || !contactNo) {
Alert.alert("Please fill all the Fields")
return
}
try {
getCounter()
Alert.alert("Item Successfully Posted..")
setAdTitle('')
setAdDescription('')
setYearOfPurchase('')
setPrice('')
setContactNo('')
setImage('')
} catch (err) {
Alert.alert("Something went wrong\nPlease try again...")
}
}
useEffect(()=>{
fireStore().collection("ads").add({
adTitle,
adDescription,
yearOfPurchase,
price,
contactNo,
image,
uniqueID: counter,
uid: Auth().currentUser.uid
})},[counter])
return <ChildElements/>
}
常量YourElement=()=>{
const getCounter=async()=>{
试一试{
const querySnap=wait fireStore().collection('Counter').doc('count').get()
setCounter((querySnap.data().counter)+1)
}捕获(错误){
警报(“出现问题\n[错误]:”+错误)
}
试一试{
等待fireStore().集合('Counter')。文档('count')。更新({
柜台:柜台
})
}抓住{
//警报(“出现问题\n请重试…”)
}
}
const postData=async()=>{
如果(!adTitle | | |!addDescription | |!购买年份| |!价格| |!联系人编号){
Alert.Alert(“请填写所有字段”)
返回
}
试一试{
getCounter()
Alert.Alert(“已成功发布的项目…”
setAdTitle(“”)
setAddDescription(“”)
setYearOfPurchase(“”)
设定价格(“”)
setContactNo(“”)
setImage(“”)
}捕捉(错误){
Alert.Alert(“出现问题\n请重试…”)
}
}
useffect(()=>{
fireStore().集合(“广告”).添加({
广告标题,
补充说明,
购买年份,
价格,
联系人号码:,
形象,,
唯一标识:计数器,
uid:Auth().currentUser.uid
})}[柜台])
返回
}
这样,只有在计数器更新后,数据才会发送到firebase。我相信您在尝试获取相同范围内的更新代码时,正在尝试访问尚未更新的变量。
您可以做一个简单的测试,看看这是否是问题所在,将代码更改为如下内容:
const getCounter = async () => {
let newCounter = null
try {
const querySnap = await fireStore().collection('Counter').doc('count').get()
newCounter = (querySnap.data().counter)+1
} catch(error) {
alert("Something went wrong\n[Error]: "+ error)
}
try {
setCounter(newCounter)
await fireStore().collection('Counter').doc("count").update({
counter: newCounter
})
} catch {
// alert("Something went wrong\nPlease try again...")
}
}
通过这种方式,您可以保证在发送之前实时计算传递给firebase的值。我相信您正在尝试