【问题标题】:Input tag looses focus on state update in react输入标签在反应中失去了对状态更新的关注
【发布时间】:2021-05-28 07:21:39
【问题描述】:

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

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

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

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

codeandbox 链接: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>
  );
}

【问题讨论】:

    标签: javascript html reactjs input


    【解决方案1】:

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

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

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

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

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

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

    类似于:

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

    sandbox

    【讨论】:

    • 感谢您回答我的问题,您能否详细说明声明 和将其作为函数调用的区别?
    • link下面有详细的解释
    【解决方案2】:

    就像组件中的组件,

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

    【讨论】:

      猜你喜欢
      • 2018-02-14
      • 2018-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多