简体   繁体   English

为什么 React 输入元素嵌套在组件中时会失去焦点?

[英]Why does a React input element lose focus when nested within a component?

So, I have an input element connected to the React Context API - updating the value onChange works when the element is not nested within a component.因此,我有一个连接到 React Context API 的输入元素 - 当元素未嵌套在组件中时,更新 onChange 值有效。 Just under the input, I render a different component that returns an input field.就在输入之下,我渲染了一个返回输入字段的不同组件。 This input field is also connected to the context API, but the input loses focus onChange.此输入字段也连接到上下文 API,但输入失去了对更改的关注。

I understand that I could add a "key" and even an "id", but none of these solutions seems to work.我知道我可以添加一个“密钥”甚至一个“id”,但这些解决方案似乎都不起作用。

Why is this happening, and what is the best way to fix is?为什么会发生这种情况,最好的解决方法是什么?

import React, { useContext } from "react";
import { Context } from "../../context";
import { set_employee_action } from "../../context/actions";

const DashBody = () => {
  const { state, dispatch } = useContext(Context);

  const DashboardBody = () => {
    return (
      <div key={"table"}>
        {/* THIS IS NOT THE ACTUAL PLACE FOR THIS INPUT - BUT THIS IS WHERE IT BREAKS */}
        <div key={"LABEL_TWO"}>
          <label htmlFor={"LABEL_TWO"}>{"LABEL_TWO"}:</label>
          <input
            type="text"
            id={"LABEL_TWO"}
            key={"LABEL_TWO"}
            name={"LABEL_TWO"}
            value={
              state.dash.employee_form["LABEL_TWO"]
                ? state.dash.employee_form["LABEL_TWO"]
                : ""
            }
            onChange={(e) => dispatch(set_employee_action(e))}
          ></input>
        </div>
        {/* THIS IS NOT THE ACTUAL PLACE FOR THIS INPUT - BUT THIS IS WHERE IT BREAKS */}
      </div>
    );
  };

  return (
    <div className="dash_body_container" key={"dash_body_container"}>
      {/* THIS IS NOT THE ACTUAL PLACE FOR THIS INPUT - BUT THIS IS WHERE IT WORKS */}
      <div key={"LABEL_ONE"}>
        <label htmlFor={"LABEL_ONE"}>{"LABEL_ONE"}:</label>
        <input
          type="text"
          id={"LABEL_ONE"}
          key={"LABEL_ONE"}
          name={"LABEL_ONE"}
          value={
            state.dash.employee_form["LABEL_ONE"]
              ? state.dash.employee_form["LABEL_ONE"]
              : ""
          }
          onChange={(e) => dispatch(set_employee_action(e))}
        ></input>
      </div>
      {/* THIS IS NOT THE ACTUAL PLACE FOR THIS INPUT - BUT THIS IS WHERE IT WORKS */}
      <DashboardBody></DashboardBody>
    </div>
  );
};

export default DashBody;

It looks like you're redefining the DashboardBody component each time DashBody is rendered.每次呈现DashBody您似乎都在重新定义DashboardBody组件。 You're losing the focus inside DashboardBody 's input because you're using dispatch from DashBody so that each time the dispatch is called, DashBody component is re-rendered and is rendering a different DashboardBody component.您正在失去DashboardBody输入中的焦点,因为您使用的是DashBody dispatch ,因此每次调用dispatchDashBody重新呈现DashBody组件并呈现不同的DashboardBody组件。 You can extract DashboardBody and define it outside DashBody but make sure you use useContext(Context) in DashboardBody :您可以提取DashboardBody并在DashBody之外定义它,但请确保在DashboardBody使用useContext(Context)

const DashboardBody = () => {
  const { state, dispatch } = useContext(Context); // make sure you have your own dispatch method

    return (
      <div key={"table"}>
        {/* THIS IS NOT THE ACTUAL PLACE FOR THIS INPUT - BUT THIS IS WHERE IT BREAKS */}
        <div key={"LABEL_TWO"}>
          <label htmlFor={"LABEL_TWO"}>{"LABEL_TWO"}:</label>
          <input
            type="text"
            id={"LABEL_TWO"}
            key={"LABEL_TWO"}
            name={"LABEL_TWO"}
            value={
              state.dash.employee_form["LABEL_TWO"]
                ? state.dash.employee_form["LABEL_TWO"]
                : ""
            }
            onChange={(e) => dispatch(set_employee_action(e))}
          ></input>
        </div>
        {/* THIS IS NOT THE ACTUAL PLACE FOR THIS INPUT - BUT THIS IS WHERE IT BREAKS */}
      </div>
    );
  };

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

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