[英]Does React re-render the entire top-level component or just the individual components within which change?
[英]Input Loses Focus Beacuse Of Re-Render, How to Make My Function On Top-Level With Pointers - React
嗨,我有一個 function,它根據它們的 ID 和父 ID 動態創建父子組件,在我將onChange
添加到輸入之前,它工作正常,現在由於重新渲染它們的父級,它們失去了焦點。
我知道我需要使它成為頂級 function 但我似乎不知道如何傳遞組件和功能。
繼承人的代碼:
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]" : ""
}`}
/>
</>
)}
</>
);
};
然后在 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>
如果您需要更多信息,我可以免費提供。
為此使用頂級組件:
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]" : ""
}`}
/>
</>
)}
</>
);
};
在你的 JSX 中,傳遞你需要傳遞的屬性。
{categories?.map((category) => <TreeForCategory category={category} />}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.