繁体   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