繁体   English   中英

React 不会使用初始值的循环数组更改输入值

[英]React doesn't change input value with looping array for initial value

如何更新状态数组中输入文本的值? 这是我目前使用的代码:

这是用于初始状态反应钩子

const [kernelSize, setKernelSize] = useState(3)
const [kernel, setKernel] = useState([])

内核大小的输入范围

<input type="range" step="2" name="range" min="3" max="7" value={kernelSize} className="slider" onChange={(e) => handleKernel(e)} />

这是用于 handleKernel 函数

const handleKernel = (e) => {
    setKernelSize(e.target.value)
    let kernel = []
    for (let i = 0; i < e.target.value; i++) {
        kernel.push([])
        for (let j = 0; j < e.target.value; j++) {
            kernel[i].push(1)
        }
    }
    setKernel(kernel)
}

这是用于从输入范围循环输入文本的大小/长度

{
kernel.map((value, index) => {
    return (
        <div className="row mt-3" key={`${index}_${value}`}>
            {
                value.map((value_2, index_2) => {
                    return (
                        <div className="input-wrap" key={`${index_2}_${value_2}`}>
                            <input type="text" id="" className="form-control" value={value_2} onChange={(e) => updateKernel(e, index, index_2)} />
                        </div>
                    )
                })
            }
        </div>
    )
})}

这是用于 updateKernel 功能

const updateKernel = (e, index, index_2) => () => {
    let kernelCopy = [...kernel];
    kernelCopy[index][index_2] = e.target.value;
    setKernel(kernelCopy);
}

看起来这里的问题是您还没有浅复制正在更新的嵌套内部数组。

const updateKernel = (e, index, index_2) => {
  // use a functional state update to update from previous state
  setKernel((kernel) =>
    // shallow copy outer array
    kernel.map((outerEl, i1) =>
      i1 === index
        // shallow copy inner array on index match
        ? outerEl.map((innerEl, i2) =>
            // update at index match or return current
            i2 === index_2 ? e.target.value : innerEl 
          )
        : outerEl
    )
  );
};

更新

由于您定义 React 键的方式,输入失去了焦点。 键使用索引和当前值,这两个值可能是您可以为 React 键选择的两个最差值。 问题是每次更改时,键现在都是不同的值,React 会卸载之前的输入并安装新的输入。

解决方案是使用稳定的密钥,这些密钥在它在 React 中表示的数据的整个生命周期中都存在。 为此,我建议使用带有键的id属性和呈现的值的value属性的对象。

这是使用uuid 包生成 GUId 的完整代码示例。

import { v4 as uuidV4 } from "uuid";

function App() {
  const [kernelSize, setKernelSize] = useState(3);
  const [kernel, setKernel] = useState([]);

  useEffect(() => {
    let kernel = [];
    for (let i = 0; i < kernelSize; i++) {
      kernel.push({
        id: uuidV4(), // <-- generate a row id
        value: []
      });
      for (let j = 0; j < kernelSize; j++) {
        kernel[i].value.push({
          id: uuidV4(), // <-- generate element id
          value: 1
        });
      }
    }
    setKernel(kernel);
  }, [kernelSize]);

  const handleKernel = (e) => {
    setKernelSize(e.target.value);
  };

  const updateKernel = (index, index2) => (e) => {
    setKernel((kernel) =>
      kernel.map((outerEl, i1) =>
        i1 === index
          ? {
              ...outerEl,
              value: outerEl.value.map((innerEl, i2) =>
                i2 === index2
                  ? {
                      ...innerEl,
                      value: e.target.value
                    }
                  : innerEl
              )
            }
          : outerEl
      )
    );
  };

  return (
    <div className="App">
      <input
        type="range"
        step="2"
        name="range"
        min="3"
        max="7"
        value={kernelSize}
        className="slider"
        onChange={handleKernel}
      />

      <div>
        {kernel.map((row, index) => {
          return (
            <div className="row mt-3" key={row.id}> // <-- use id as React key
              {row.value.map(({ id, value }, index_2) => {
                return (
                  <span className="input-wrap" key={id}> // <-- use id as React key
                    <input
                      style={{
                        width: "2rem"
                      }}
                      type="text"
                      id=""
                      className="form-control"
                      value={value}
                      onChange={updateKernel(index, index_2)}
                    />
                  </span>
                );
              })}
            </div>
          );
        })}
      </div>
    </div>
  );
}

编辑 react-doesnt-change-input-value-with-looping-array-for-initial-value

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM