简体   繁体   English

由于重新渲染,输入失去焦点,如何使用指针使我的 Function 在顶层 - React

[英]Input Loses Focus Beacuse Of Re-Render, How to Make My Function On Top-Level With Pointers - React

Hi i have a function that dynamically creates parent-child components based on their ID and Parent ID, which worked fine until i added onChange to the inputs, now they lose focus because of the re-rendering of their parent.嗨,我有一个 function,它根据它们的 ID 和父 ID 动态创建父子组件,在我将onChange添加到输入之前,它工作正常,现在由于重新渲染它们的父级,它们失去了焦点。

I know i need to make it top-level function but i dont seem to get how to pass the components and functions along.我知道我需要使它成为顶级 function 但我似乎不知道如何传递组件和功能。

Heres the code:继承人的代码:

const createItemsFromTree = (fromTree) => {
    return (
      <>
        {fromTree.children?.length ? (
          <>
            <CustomTreeItem
              className={`json-display ${fromTree.placeholder}`}
              key={fromTree.id}
              label={
                <div className="flex items-center gap-1 border border-[#e0dbdb] rounded-lg px-2 min-h-[36px] w-full my-[5px]">
                  <input
                    type="text"
                    className="outline-none text-[12px] w-full"
                    placeholder={
                      fromTree.parentId ? "Sub-Category" : "Category"
                    }
                    value={fromTree.name && fromTree.name}
                    onChange={(e) =>
                      handleCategoryInputChange(fromTree.id, e.target.value)
                    }
                  />
                  {!fromTree.firstCategory && (
                    <Button
                      icon={<FaTimes color="#adadad" size={14} />}
                      title={!fromTree.parentId ? "" : ""}
                      onClick={() => handleRemovecategory(fromTree.id)}
                      customClasses={`w-fit text-[10px] p-0 m-0 mx-0 mr-0 py-0 px-0  bg-transparent `}
                    />
                  )}

                  <Button
                    icon={<AiOutlinePlusSquare color="#bcbcbc" size={20} />}
                    title={!fromTree.parentId ? "" : ""}
                    containerClass="float-right"
                    onClick={() => handleAddSubCategory(fromTree.id)}
                    customClasses={`w-fit text-[10px] p-0 m-0 mx-0 mr-0 py-0 px-0  bg-transparent absolute translate-x-[12px]  ${
                      !fromTree.children?.length ? "mr-[30px]" : ""
                    }`}
                  />
                </div>
              }
              nodeId={fromTree.id}
              defaultExpanded={[fromTree.id, fromTree.parentId]}
              onClick={() => console.log(fromTree)}
            >
              {fromTree.children.length > 0 &&
                fromTree.children.map((child) => createItemsFromTree(child))}
            </CustomTreeItem>
          </>
        ) : (
          <>
            <CustomTreeItem
              className={`json-display ${fromTree.placeholder}`}
              key={fromTree.id}
              label={
                <div
                  className={`flex items-center gap-1 border border-[#e0dbdb] rounded-lg px-2 min-h-[36px] w-full ${
                    fromTree.children.length || !fromTree.parentId
                      ? ""
                      : "ml-[20px]"
                  } my-[5px]`}
                >
                  <input
                    type="text"
                    className="outline-none text-[12px] w-full"
                    placeholder={
                      fromTree.parentId ? "Sub-Category" : "Category"
                    }
                    value={fromTree.name && fromTree.name}
                    onChange={(e) =>
                      handleCategoryInputChange(fromTree.id, e.target.value)
                    }
                  />
                  {!fromTree.firstCategory && (
                    <Button
                      icon={<FaTimes color="#adadad" size={14} />}
                      title={!fromTree.parentId ? "" : ""}
                      onClick={() => handleRemovecategory(fromTree.id)}
                      customClasses={`w-fit text-[10px] p-0 m-0 mx-0 mr-0 py-0 px-0  bg-transparent `}
                    />
                  )}
                </div>
              }
              nodeId={fromTree.id}
              defaultExpanded={[fromTree.id, fromTree.parentId]}
              onClick={() => console.log(fromTree)}
            />
            <Button
              icon={<AiOutlinePlusSquare color="#bcbcbc" size={20} />}
              title={!fromTree.parentId ? "" : ""}
              containerClass="float-right"
              onClick={() => handleAddSubCategory(fromTree.id)}
              customClasses={`w-fit text-[10px] p-0 m-0 mx-0 mr-0 py-0 px-0  bg-transparent translate-y-[-23px] translate-x-[3px] absolute ${
                !fromTree.children?.length ? "mr-[30px]" : ""
              }`}
            />
          </>
        )}
      </>
    );
  };

Then in the jsx i call it like this:然后在 jsx 中我这样称呼它:

  <TreeView
                  aria-label="file system navigator"
                  expanded={expanded}
                  onNodeToggle={handleToggle}
                  defaultCollapseIcon={<ExpandMoreIcon />}
                  defaultExpandIcon={<ChevronRightIcon />}
                  sx={{
                    height: 240,
                    flexGrow: 1,
                    maxWidth: 400,
                    overflowY: "auto",
                  }}
                >
                  {categories?.map((category) => createItemsFromTree(category))}
                </TreeView>

If you need more information i can provide freely.如果您需要更多信息,我可以免费提供。

Use a top level component for that:为此使用顶级组件:

const CategoryTree = ({ category }) => {
    return (
      <>
        {fromTree.children?.length ? (
          <>
            <CustomTreeItem
              className={`json-display ${fromTree.placeholder}`}
              key={fromTree.id}
              label={
                <div className="flex items-center gap-1 border border-[#e0dbdb] rounded-lg px-2 min-h-[36px] w-full my-[5px]">
                  <input
                    type="text"
                    className="outline-none text-[12px] w-full"
                    placeholder={
                      category.parentId ? "Sub-Category" : "Category"
                    }
                    value={fromTree.name && fromTree.name}
                    onChange={(e) =>
                      handleCategoryInputChange(fromTree.id, e.target.value)
                    }
                  />
                  {!fromTree.firstCategory && (
                    <Button
                      icon={<FaTimes color="#adadad" size={14} />}
                      title={!fromTree.parentId ? "" : ""}
                      onClick={() => handleRemovecategory(fromTree.id)}
                      customClasses={`w-fit text-[10px] p-0 m-0 mx-0 mr-0 py-0 px-0  bg-transparent `}
                    />
                  )}

                  <Button
                    icon={<AiOutlinePlusSquare color="#bcbcbc" size={20} />}
                    title={!fromTree.parentId ? "" : ""}
                    containerClass="float-right"
                    onClick={() => handleAddSubCategory(category.id)}
                    customClasses={`w-fit text-[10px] p-0 m-0 mx-0 mr-0 py-0 px-0  bg-transparent absolute translate-x-[12px]  ${
                      !category.children?.length ? "mr-[30px]" : ""
                    }`}
                  />
                </div>
              }
              nodeId={fromTree.id}
              defaultExpanded={[fromTree.id, fromTree.parentId]}
              onClick={() => console.log(fromTree)}
            >
              {fromTree.children.length > 0 &&
                fromTree.children.map((child) => createItemsFromTree(child))}
            </CustomTreeItem>
          </>
        ) : (
          <>
            <CustomTreeItem
              className={`json-display ${fromTree.placeholder}`}
              key={fromTree.id}
              label={
                <div
                  className={`flex items-center gap-1 border border-[#e0dbdb] rounded-lg px-2 min-h-[36px] w-full ${
                    fromTree.children.length || !fromTree.parentId
                      ? ""
                      : "ml-[20px]"
                  } my-[5px]`}
                >
                  <input
                    type="text"
                    className="outline-none text-[12px] w-full"
                    placeholder={
                      category.parentId ? "Sub-Category" : "Category"
                    }
                    value={fromTree.name && fromTree.name}
                    onChange={(e) =>
                      handleCategoryInputChange(fromTree.id, e.target.value)
                    }
                  />
                  {!fromTree.firstCategory && (
                    <Button
                      icon={<FaTimes color="#adadad" size={14} />}
                      title={!fromTree.parentId ? "" : ""}
                      onClick={() => handleRemovecategory(fromTree.id)}
                      customClasses={`w-fit text-[10px] p-0 m-0 mx-0 mr-0 py-0 px-0  bg-transparent `}
                    />
                  )}
                </div>
              }
              nodeId={fromTree.id}
              defaultExpanded={[fromTree.id, fromTree.parentId]}
              onClick={() => console.log(fromTree)}
            />
            <Button
              icon={<AiOutlinePlusSquare color="#bcbcbc" size={20} />}
              title={!fromTree.parentId ? "" : ""}
              containerClass="float-right"
              onClick={() => handleAddSubCategory(category.id)}
              customClasses={`w-fit text-[10px] p-0 m-0 mx-0 mr-0 py-0 px-0  bg-transparent translate-y-[-23px] translate-x-[3px] absolute ${
                !category.children?.length ? "mr-[30px]" : ""
              }`}
            />
          </>
        )}
      </>
    );
  };

In your JSX, and pass down the property you need to pass.在你的 JSX 中,传递你需要传递的属性。

{categories?.map((category) => <TreeForCategory category={category} />}

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

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