簡體   English   中英

子組件表單提交后反應不更新父組件上的數據

[英]React not updating data on parent component after child component form submit

我有一個父組件,在提交子組件上的表單時應該更新它。 在子組件中提交表單時,調用了fetchData function,但是這里的父組件沒有更新數據,需要刷新頁面才能更新數據:

{JSON.stringify(data)}

我無法將 setState 中的數據添加到 useEffect,因為它會創建一個無限循環。

從子組件提交表單時,如何更新父組件上的數據?

父組件

export function ParentComponent() {
    const [data, setData] = useState(null);

    const fetchData = async () => {

        const result = await axios(
          '/api/info/'
          );
          setData(result.data)
    }

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


      return (
        <div>
            <h1>
                Parent Page
            </h1>
            
            {JSON.stringify(data)}

            <ChildComponent dataUpdated={fetchData} />
        </div>
    )
}

子組件

export function ChildComponent(props) {
    const [formData, setFormData] = useState('');

    const handleSubmit = evt => {
            evt.preventDefault();
            axios.post(`/api/info/create`,
                        {formData}
                  )
                  .then(response => { return response.data })
                  .then(props.dataUpdated()) // calling this function does not update the data on the parent component
        }
        
    return (
        <div>
            <h1>
                Child Component
            </h1>

            <form className={classes.form} onSubmit={handleSubmit}>
                    <TextField value={formData.number}
                        id="filled-number"
                        label="number"
                        type="number"
                        onChange={evt => setFormData({...formData, number: evt.target.value})}
                    />

                    <Button
                        type="submit"
                    >
                        Submit
                    </Button>
            </form>
        </div>
    )
}

您必須從此行中刪除括號:

.then(props.dataUpdated())

所以它是:

.then(props.dataUpdated)

為什么?

好吧,這是Promise的常見錯誤(我認為它是從axios.post()返回的),即我們傾向於忘記Promisethencatchfinally函數的參數應該是異步執行的隨着Promise返回。

Otherwise, a Promise is like a regular class / object and in this case you're synchronously running its then function two times with different arguments. 但像往常一樣,當我們向 function (即 function 調用本身)提供參數時,此調用首先執行,其返回值作為實際參數給出。

所以當你這樣做時:

.then(props.dataUpdated())

...您正在同步(即在Promise返回之前)運行props.dataUpdated function 並將其返回值作為參數傳遞給then 由於props.dataUpdated = fetchData返回undefined (沒有返回值),這與:

.then(undefined)

......這不起作用。

Remember, the argument function is supposed to be executed asynchronously at a later stage (when the Promise ) but now instead you run it instantly and then leave the then function with an undefined to execute when the Promise . 由於尚未發生更改的 state,因此在這個過早的時間運行更新 function 不會產生任何結果,並且由於運行undefined為 function,因此您稍后也不會使用結果更新的 UI正如預期的那樣(從then嘗試將undefined作為函數運行時,控制台中也可能出現錯誤)。

把它們加起來...

...您需要為then提供一個可執行的 function ,其中包含您想要在Promise異步返回時運行的邏輯(就像您在第一個中所做的then )。 最簡單的方法是:

.then(props.dataUpdated) // forwarding the function given in props

...但你也可以這樣做:

.then(res => props.dataUpdated()) // arrow function calling the function given in props

或者

.then(res => { props.dataUpdated() }) // arrow function with body calling the function given in props

...如果您想對上一步的輸入(即您從then一步返回的值( response.data ))做一些事情,這會更方便。

參考

暫無
暫無

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

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