输入标签在反应中失去对状态更新的关注

时间:2021-05-28 07:21:39

标签: javascript html reactjs input

这是一个非常简单的应用程序,我为 2 个案例声明了 2 个状态

在情况 1 中,我使用状态 dataArray1 并创建一个输入标签数组。

在情况 2 中,我使用状态 dataArray2 并创建一个数组,其中只包含一个输入标签

现在的问题是,如果情况 1 用户界面按要求运行,但在情况 2 中,当我们输入任何内容时,输入会失去焦点。我想了解为什么会发生这种情况以及如何解决它...

代码和框的链接:https://codesandbox.io/s/dreamy-dubinsky-x8t6c?file=/src/App.js

这是代码...

import { useState } from "react";
import "./styles.css";

export default function App() {
  const [dataArray1, setDataArray1] = useState([
    "Hello",
    "My name is testBot",
    "I am a student"
  ]);

  const [dataArray2, setDataArray2] = useState([
    "Hello",
    "My name is testBot",
    "I am a student"
  ]);

  const generateUI1 = (data) => {
    console.log(data);
    return data.map((e, i) => {
      return (
        <div key={`type1Key${i}`}>
          <input
            value={data[i]}
            onChange={(e) => {
              let newData = [...data];
              newData[i] = e.target.value;
              setDataArray1(newData);
            }}
          />
        </div>
      );
    });
  };

  const InputComponent = (props) => {
    return (
      <input
        value={props.data[props.i]}
        onChange={(e) => {
          let newData = [...props.data];
          newData[props.i] = e.target.value;
          setDataArray2(newData);
        }}
        // key={`new${props.i}`}
      />
    );
  };
  const generateUI2 = (data) => {
    console.log(data);
    return data.map((e, i) => {
      return (
        <div key={`${data[i]}`}>
          <InputComponent data={data} i={i} key={`type2Key${i}`} />
        </div>
      );
    });
  };

  return (
    <div className="App">
      <div>
        <h1>Case 1</h1>
        {generateUI1(dataArray1)}
      </div>
      <div>
        <h1>Case 2</h1>
        {generateUI2(dataArray2)}
      </div>
    </div>
  );
}

2 个答案:

答案 0 :(得分:2)

您正在导致重新渲染,这将导致失去焦点。 因此,您可以将您的组件移动到 App() 范围之外,就像他的回答中描述的用户“zb22”一样。 或者像这样调用您的组件:

<InputComponent data={data} i={i} />

你可以像调用方法一样调用它:

InputComponent({ data: data, i: i })

另外,请记住不要随数据一起更改密钥。 现在,当您的数据更改时,您的密钥会更改,这将导致重新渲染 因此,请从以下位置更改您的密钥:

<div key={`${data[i]}`}>

类似于:

<div key={`ui2_${i}`}>

sandbox

答案 1 :(得分:1)

就像组件内的组件,

您需要将 InputComponent 组件与 App 组件分开。 并将 setDataArray2 作为道具传递给它。

import { useState } from "react";
import "./styles.css";

const InputComponent = (props) => {
  return (
    <input
      value={props.data[props.i]}
      onChange={(e) => {
        let newData = [...props.data];
        newData[props.i] = e.target.value;
        props.setDataArray2(newData);
      }}
    />
  );
};

export default function App() {
  const [dataArray1, setDataArray1] = useState([
    "Hello",
    "My name is testBot",
    "I am final year student"
  ]);

  const [dataArray2, setDataArray2] = useState([
    "Hello",
    "My name is testBot",
    "I am final year student"
  ]);

  const generateUI1 = (data) => {
    console.log(data);
    return data.map((e, i) => {
      return (
        <div key={`type1Key${i}`}>
          <input
            value={data[i]}
            onChange={(e) => {
              let newData = [...data];
              newData[i] = e.target.value;
              setDataArray1(newData);
            }}
          />
        </div>
      );
    });
  };

  const generateUI2 = (data) => {
    console.log(data);
    return data.map((e, i) => {
      return (
        <div key={`type1Key${i}`}>
          <InputComponent data={data} i={i} setDataArray2={setDataArray2}/>
        </div>
      );
    });
  };

  return (
    <div className="App">
      <h3>This is a very simple app, I have declared 2 states for 2 cases</h3>
      <ol>
        <li>
          {` In case 1, I am using the state dataArray1 and creating a array of input tag
`}
        </li>
        <li>
          {`In case 2, I am using state dataArray2 and creating an array of
          <InputComponent /> where <InputComponent /> just contains a input tag`}
        </li>
      </ol>
      <p>
        Now the issue is this, in case1 UI is functioning as required but in
        case 2 the input loses its focus when we type anything.
      </p>

      <div>
        <h1>Case 1</h1>
        {generateUI1(dataArray1)}
      </div>
      <div>
        <h1>Case 2</h1>
        {generateUI2(dataArray2)}
      </div>
    </div>
  );
}

在此sandbox

中查看