React Hooks:状态变量在事件处理程序中具有错误值,无法输入输入

Bha*_*rat 2 javascript reactjs react-hooks

下面,我正在渲染<App/>带有子组件的组件作为<Input/>组件数组。我使用“添加新”按钮添加了一些输入。我可以添加输入文本组件。但是,当我在文本中输入值时,它没有显示。我无法修改状态数组中的对象,因为索引在setData函数中显示为“-1”。因此,当我们在文本框中键入内容时,值不会显示。请让我知道为什么state[]我在函数中访问时setData

    function Input(props)
    {
        return (
            <div>
                <label htmlFor='variable'>Name</label>
                <input id='variable'
                    type='text'
                    value={props.value}
                    onChange={(e) => props.setData(props.id, e.target.value)} />

            </div>
        )
    }
    function App()
    {
        let [state, setState] = React.useState([])
        let [inputs, setInputs] = React.useState([])
        let setData = ((id, value) =>
        {
            console.log(state); // prints []
            let index = state.findIndex(ele => ele.key === id);
            console.log(index); // prints -1
            if (!(index === -1))
            {
                setState(state =>
                {
                    state[idx]["value"] = value;
                })
            }
        })
        let handleAdd = () =>
        {
            let idx = `${new Date().getTime()}`
            let tempState = {
                "key": idx,
                "value": "",
            }
            setState(state => [...state, tempState])
            let input = <Input key={tempState.key}
                value={tempState.value}
                id={tempState.key}
                setData={setData} />
            setInputs(inputs => [...inputs, input])
        }
        return (
            <div>
                <button onClick={handleAdd}>add new</button>
                <div>
                    {inputs}
                </div>
            </div>
        )
    }
Run Code Online (Sandbox Code Playgroud)

Cla*_*ity 6

Input当您在内部创建组件时handleAdd,它会创建一个闭包,并因此setData获取创建组件时存在的状态,而缺少新添加的状态。

一般来说,创建组件并将它们保存到状态并不是一个好方法。相反,最好只将数据保存到状态并基于它渲染组件。

这是执行此操作的一种方法,请注意组件及其逻辑有多么简单。

function App() {
  let [state, setState] = React.useState([]);

  let setData = (id, value) => {
    const newState = state.map((st) => {
      if (st.key === id) {
        st.value = value;
      }

      return st;
    });

    setState(newState);
  };

  const addInput = () => {
    const idx = `${new Date().getTime()}`;
    setState([...state, { key: idx, value: '' }]);
  };

  return (
    <div>
      <button onClick={addInput}>add new</button>
      <div>
        {state.map((st) => (
          <Input value={st.value} key={st.key} setData={setData} id={st.key} />
        ))}
      </div>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

  • 嗯,也许它不是严格意义上的闭包,但基本上“setData”在创建后不知道任何有关状态更改的信息,因为组件的每个实例都有自己的该函数的实例。 (2认同)