繁体   English   中英

输入标签失去对 state 更新的关注

[英]Input tag looses focus on state update in react

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

在案例 1 中,我使用 state dataArray1 并创建一个输入标签数组。

在情况 2 中,我使用 state 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>
  );
}

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

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

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

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

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

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

类似于:

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

沙盒

就像组件中的组件,

您需要将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>
  );
}

在这个沙箱中检查它

暂无
暂无

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

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