gpt4 book ai didi

reactjs - 传递到其他功能组件的回调是否在刷新时更新?

转载 作者:行者123 更新时间:2023-12-04 07:48:01 25 4
gpt4 key购买 nike

我有一个复杂的表单,其中包含不同类型的输入元素。为简单起见,我将其限制为一个,因为每个都有效地遵循相同的方法。

const Form = () => {
const [state, setState] = useState();

const handleChange = useCallback((name, value) => {
setState({
...state,
[name]: value
})
}, [state, setState]);

useEffect(() => {
console.log(state)
}, [state, setState]);

return (
<div>
<Input name="inputOne" onChange={handleChange} />
<Input name="inputTwo" onChange={handleChange} />
</div>
);
}

const Input = ({ name, onChange }) => {
const [value, setValue] = useState("");

const handleChange = useCallback((e) => {
setValue(e.target.value);
onChange(name, e.target.value)
}, [value, setValue]);

return (
<input onChange={handleChange} value={value}/>
);
}
出于某种原因,使用此表格时。如果我在第一个输入中输入值,我会将结果记录为
{ "inputOne": "value entered into input one" }
但是如果我在第二个输入中输入一些东西,我就会得到这个
{ "inputTwo": "value entered into input two" }
如果我返回并输入 inputOne我们再次得到这个。
{ "inputOne": "value entered into input one, and more text entered" }   
据我所知,我编写的代码应该在状态更改时更新回调,因此传播的新状态 (...state) 是最新的状态值。然后在我通过 handleChange 的所有元素中更新。功能成。然而,似乎 handleChange在传递到 onChange 的地方不会更新参数,所以旧的回调被调用,状态属性被错误地保存。
有人能告诉我这是否正确以及 handleChange回调未正确更新?就像两个 Input 都看到了对 handleChange 的不同引用。打回来。

最佳答案

你的问题是一个非常典型闭包问题 .
关于如何获得旧引用资料非常复杂,但让我尽量解释它
创建表单组件时,handleChange 函数会在每次状态更改时更新,并传递给 Input 组件。然而,即使更新的实例被传递给子进程,子进程也不会使用更新的实例,除非它自己的值改变了。现在,当它尝试更新其值时,它正在调用旧的引用函数,该函数没有反射(reflect)其他输入值。
有两种方法可以解决这个问题

  • 使用回调方法设置状态,以便通过 react 为您提供最新状态,而不管其闭包中的值
  • 另一种解决方法是在 Input 组件中添加 onChange 作为 useCallback 的依赖,这样即使其他 input 元素导致 state 发生变化,所有 Input 都有 onChange 函数的最新引用

  • const { useCallback, useState, useEffect } = React;
    const Form = () => {
    const [state, setState] = useState({});

    const handleChange = useCallback((name, value) => {
    setState(prev=> ({
    ...prev,
    [name]: value
    }))
    }, [setState]);

    useEffect(() => {
    console.log(state);
    }, [state, setState]);

    return (
    <div>
    <Input name="inputOne" onChange={handleChange} />
    <Input name="inputTwo" onChange={handleChange} />
    </div>
    );
    }

    const Input = ({ name, onChange }) => {
    const [value, setValue] = useState("");

    const handleChange = useCallback((e) => {
    setValue(e.target.value);
    onChange(name, e.target.value)
    }, [value, setValue]);

    return (
    <input onChange={handleChange} value={value}/>
    );
    }

    ReactDOM.render(<Form />, document.getElementById('app'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
    <div id="app" />

    附言如果您正在使用 useCallback并且将状态添加为依赖项并且您正在更新状态本身,它不会实现任何目标,因为每次更新时都会创建一个单独的实例。
    最好使用函数式方法来 setState解决这个问题并更好地内存

    关于reactjs - 传递到其他功能组件的回调是否在刷新时更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67113159/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com