簡體   English   中英

從 Firestore 獲取值時 useState 不更新

[英]useState not updating when getting values from Firestore

我正在 React 中創建一個 Update Post 組件。 該組件從 Firestore 獲取現有的發布數據並使用表單更新這些字段。

編輯:短版:

  1. 我想從 Firestore 獲取發布數據 - 工作
  2. 我想用該數據設置 state - 不工作
  3. 如果輸入更改,我想從表單更新 state - 不工作

長版:

我想最初將表單中所有字段的 state 設置為帖子中的現有值,然后在輸入字段更改(更新)時更新此 state。

問題是:

  1. useEffect 沒有更新 state。它應該運行一次並設置表單的所有現有字段值,如果不是所有字段都被更新,那么如果一個字段沒有更新,它會保持原樣。 但是,useEffect 中的 console.log 什么也不返回,而表單中的占位符值沒問題。 這導致 updatePost() function 失敗。

導出默認值 function EditPost() {

// establish state for the form
const [postValue, setPostValue] = useState('')
const [postValueTwo, setPostValueTwo] = useState('')

// state for the query data below
const [postData, setPostData] = useState([])

async function getPost() {
    ...
    setPostData(doc.data());
}

// empty array = SHOULD run once 'after mount'
useEffect(() => {
    // run the query
    getPost();
    // set the state
    setPostValue(postData.someValue)
    setPostValueTwo(postData.anotherValue)
    console.log(postValue) // this returns undefined
},[])

// send data to Firestore
async function updatePost(e) {
    e.preventDefault() 
    return await useFireStore
        .collection('posts')
        ...
        .update({
            postValue: postValue,
            postValueTwo: postValueTwo
        });
}
return (
    <>
        <div>Post Value = {postValue}</div>
        <form onSubmit={editPost}>
            <input 
                type="text"
                placeholder={postData.someValue}
                onChange={(e) => setPostValue(e.target.value)}
            />
            <input 
                type="text"
                placeholder={postData.anotherValue}
                onChange={(e) => setPostValueTwo(e.target.value)}
            />
        </form>
    </>
)
}

如果您在表單之前看到 div 標記,則 postValue 變量為空。 我知道 useEffect 在呈現 DOM 之后運行,這可以解釋這是空的,但我不明白為什么 useEffect 中的 console.log 也是空的。

編輯 => 輸入后我在 useEffect 中意識到 getPost function 當然是異步的,因此在設置 state 之前可能不會返回值,所以我將 state 設置代碼移動到 getPost function 以在查詢完成后運行成功,如下所示,但問題仍然存在。

async function getPost() {
    ...
    if (!doc.exists) {
        console.log('No such document!');
    } else {
        setPostData(doc.data());

        setPostValue(postData.someValue)
        setPostValueTwo(postData.anotherValue)
        console.log("url is: ",url)
    }
}

useEffect(() => {
    getPost();
},[])

抱歉這個冗長的問題,有時很難解釋。 非常感謝您對此提供的任何幫助。 干杯,馬特

postData是本地const 它永遠不會改變,這不是setPostData試圖做的。 調用setPostData只是告訴 React 再次渲染組件。 在那個新的渲染器上,將使用新值創建一個新的本地const ,但是您現在正在運行的代碼無法在不同的閉包中訪問該未來值。

如果您需要使用新值,則需要使用您自己的局部變量。 在你的第二個版本中,它全部在getPost function 中完成,它看起來像:

async function getPost() {
  ...
  if (!doc.exists) {
    console.log('No such document!');
  } else {
    const newData = doc.data();
    setPostData(newData);
    setPostValue(newData.someValue);
    setpostValuetwo(newData.anotherValue);
  }
}

如果你想讓它更接近你的第一個版本,那么你需要返回值並在 useEffect 中使用它:

async function getPost() {
  ...
  if (!doc.exists) {
    console.log('No such document!');
  } else {
    const newData = doc.data();
    setPostData(newData);
    return newData;
  }
}

// ...

useEffect(() => {
  (async () => {
    const newData = await getPost();
    setPostValue(newData.someValue)
    setPostValueTwo(newData.anotherValue)
  })();
},[])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM