当我在 REACT 中单击项目时,如何应用其余项目的样式?
How to apply the style of the rest of the items when I click item in REACT?
图片1
图片2
pic3
当我select一件商品时,我想应用一件商品的新样式和其余商品的原始样式
例子
当我点击 SubBookmark33 时
当前
pic1 -> pic2
但我想
pic1 -> pic3
BookmarksFolder.js
import BookmarksFolderNode from './BookmarksFolderNode';
import classes from './BookmarksFolder.module.css';
import { folders } from '../../resources/data';
function BookmarksFolder() {
return (
<div className={classes.bookmarksFolder}>
{folders.map((folder) => (
<BookmarksFolderNode
key={folder.id}
folder={folder}
/>
))}
</div>
);
}
export default BookmarksFolder;
BookmarksFolderNode.js
import { useState, useRef } from 'react';
import { AiFillCaretDown, AiFillCaretRight } from 'react-icons/ai';
import Folder from '../../resources/img/folder.svg';
import OpenedFolder from '../../resources/img/opened_folder.svg';
import classes from './BookmarksFolderNode.module.css';
function BookmarksFolderNode(props) {
const [folderIsOpen, setFolderIsOpen] = useState(false);
const tab = useRef();
const img = useRef();
const title = useRef();
const selectFolderHandler = () => {
tab.current.style.backgroundColor = '#1a73eb';
img.current.src = OpenedFolder;
title.current.style.color = '#1a73eb';
};
const openFolderHandler = () => {
setFolderIsOpen((prevState) => !prevState);
};
const paddingLeft = 20 * (props.folder.depth - 1);
return (
<div className={classes.bookmarksFolderNode}>
<div className={classes.bookmarksMainFolderNode}>
<div className={classes.verticalTab} ref={tab}></div>
<div className={classes.innerContainer} style={{paddingLeft}}>
<div className={classes.icon} onClick={openFolderHandler}>
{folderIsOpen ? (
<AiFillCaretDown className={classes.ironIcon} />
) : (
<AiFillCaretRight className={classes.ironIcon} />
)}
</div>
<img src={Folder} className={classes.folderIcon} ref={img} />
<div
className={classes.menuLabel}
onClick={selectFolderHandler}
ref={title}
>
{props.folder.title}
</div>
</div>
</div>
<div className={classes.bookmarksSubFolderNode}>
{props.folder.subFolder &&
props.folder.subFolder.map((subFolder) => (
<BookmarksFolderNode key={subFolder.id} folder={subFolder} />
))}
</div>
</div>
);
}
export default BookmarksFolderNode;
data.js
export const folders = [
{
id: 1,
depth: 1,
title: 'Bookmark 1',
subFolder: [
{
id: 1,
depth: 2,
title: 'SubBookmark 1',
subFolder: [
{
id: 1,
depth: 3,
title: 'SubBookmark 11',
},
{
id: 2,
depth: 3,
title: 'SubBookmark 22',
},
{
id: 3,
depth: 3,
title: 'SubBookmark 33',
subFolder: [
{
id: 1,
depth: 4,
title: 'SubBookmark 111',
},
],
},
],
},
{
id: 2,
depth: 2,
title: 'SubBookmark 2',
},
],
},
];
您的问题似乎是您只是在编辑当前单击的节点。您需要做的是在“selectFolderHandler”中重置所有其他项目的图像。
一种方法是遍历每个项目,并将图像设置为初始图像,然后更改当前选择的(由于性能不明智)。
建议的方法是找到一个打开的文件夹图像(如果存在)并重置它。最简单的是通过 class 或 ref 属性搜索。
想法是,当您 select 一个文件夹时,您应该从父组件 BookmarksFolder
中删除 select 其他文件夹。解决方案有点棘手,因为您 select 使用 BookmarksFolderNode
本地状态的文件夹(我的意思是 folderIsOpen
)。
好吧,让我们开始使用父组件的状态到 select/deselect 文件夹:
import BookmarksFolderNode from './BookmarksFolderNode';
import classes from './BookmarksFolder.module.css';
import { folders } from '../../resources/data';
function BookmarksFolder() {
const [foldersSelected, setFoldersSelected] = useState(new Array(folders.length).fill(false));
const selectFolder = (index) => {
let result = new Array(folders.length).fill(false);
result[index] = true;
setFoldersSelected(result);
}
return (
<div className={classes.bookmarksFolder}>
{folders.map((folder, index) => (
<BookmarksFolderNode
key={folder.id}
folder={folder}
isSelected={foldersSelected[index]}
select={(index) => selectFolder(index)}
index={index}
/>
))}
</div>
);
}
export default BookmarksFolder;
所以现在 BookmarksFolderNode
我们必须使用 isSelected
和 select
而不是 folderIsOpen
和 openFolderHandler
。不仅如此,我们还必须为子文件夹复制相同的逻辑:
import { useState, useRef, useEffect } from 'react';
import { AiFillCaretDown, AiFillCaretRight } from 'react-icons/ai';
import Folder from '../../resources/img/folder.svg';
import OpenedFolder from '../../resources/img/opened_folder.svg';
import classes from './BookmarksFolderNode.module.css';
function BookmarksFolderNode(props) {
const [subfoldersSelected, setSubFoldersSelected] = useState(new Array(props.folder.subFolder.length).fill(false));
const tab = useRef();
const img = useRef();
const title = useRef();
useEffect(() => {
if (props.isSelected) {
tab.current.style.backgroundColor = '#1a73eb';
img.current.src = OpenedFolder;
title.current.style.color = '#1a73eb';
}
else {
tab.current.style.backgroundColor = 'black';
img.current.src = Folder;
title.current.style.color = 'black';
}
}, [props.isSelected])
const openFolderHandler = () => {
props.select(props.index)
};
const paddingLeft = 20 * (props.folder.depth - 1);
const selectSubfolder = (index) => {
let result = new Array(props.folder.subFolder.length).fill(false);
result[index] = true;
setSubFoldersSelected(result);
}
return (
<div className={classes.bookmarksFolderNode}>
<div className={classes.bookmarksMainFolderNode}>
<div className={classes.verticalTab} ref={tab}></div>
<div className={classes.innerContainer} style={{paddingLeft}}>
<div className={classes.icon} onClick={openFolderHandler}>
{props.isSelected ? (
<AiFillCaretDown className={classes.ironIcon} />
) : (
<AiFillCaretRight className={classes.ironIcon} />
)}
</div>
<img src={Folder} className={classes.folderIcon} ref={img} />
<div
className={classes.menuLabel}
onClick={openFolderHandler}
ref={title}
>
{props.folder.title}
</div>
</div>
</div>
<div className={classes.bookmarksSubFolderNode}>
{props.folder.subFolder &&
props.folder.subFolder.map((subFolder, index) => (
<BookmarksFolderNode key={subFolder.id} folder={subFolder} index={index} isSelected={subfoldersSelected[index]} select={(index) => selectSubfolder(index)} />
))}
</div>
</div>
);
}
export default BookmarksFolderNode;
所以现在,如果您 select 一个文件夹(或子文件夹),其他文件夹(或子文件夹)将被删除select并且 useEffect
将应用所需的 css.
图片1
图片2
pic3
当我select一件商品时,我想应用一件商品的新样式和其余商品的原始样式
例子
当我点击 SubBookmark33 时
当前
pic1 -> pic2
但我想
pic1 -> pic3
BookmarksFolder.js
import BookmarksFolderNode from './BookmarksFolderNode';
import classes from './BookmarksFolder.module.css';
import { folders } from '../../resources/data';
function BookmarksFolder() {
return (
<div className={classes.bookmarksFolder}>
{folders.map((folder) => (
<BookmarksFolderNode
key={folder.id}
folder={folder}
/>
))}
</div>
);
}
export default BookmarksFolder;
BookmarksFolderNode.js
import { useState, useRef } from 'react';
import { AiFillCaretDown, AiFillCaretRight } from 'react-icons/ai';
import Folder from '../../resources/img/folder.svg';
import OpenedFolder from '../../resources/img/opened_folder.svg';
import classes from './BookmarksFolderNode.module.css';
function BookmarksFolderNode(props) {
const [folderIsOpen, setFolderIsOpen] = useState(false);
const tab = useRef();
const img = useRef();
const title = useRef();
const selectFolderHandler = () => {
tab.current.style.backgroundColor = '#1a73eb';
img.current.src = OpenedFolder;
title.current.style.color = '#1a73eb';
};
const openFolderHandler = () => {
setFolderIsOpen((prevState) => !prevState);
};
const paddingLeft = 20 * (props.folder.depth - 1);
return (
<div className={classes.bookmarksFolderNode}>
<div className={classes.bookmarksMainFolderNode}>
<div className={classes.verticalTab} ref={tab}></div>
<div className={classes.innerContainer} style={{paddingLeft}}>
<div className={classes.icon} onClick={openFolderHandler}>
{folderIsOpen ? (
<AiFillCaretDown className={classes.ironIcon} />
) : (
<AiFillCaretRight className={classes.ironIcon} />
)}
</div>
<img src={Folder} className={classes.folderIcon} ref={img} />
<div
className={classes.menuLabel}
onClick={selectFolderHandler}
ref={title}
>
{props.folder.title}
</div>
</div>
</div>
<div className={classes.bookmarksSubFolderNode}>
{props.folder.subFolder &&
props.folder.subFolder.map((subFolder) => (
<BookmarksFolderNode key={subFolder.id} folder={subFolder} />
))}
</div>
</div>
);
}
export default BookmarksFolderNode;
data.js
export const folders = [
{
id: 1,
depth: 1,
title: 'Bookmark 1',
subFolder: [
{
id: 1,
depth: 2,
title: 'SubBookmark 1',
subFolder: [
{
id: 1,
depth: 3,
title: 'SubBookmark 11',
},
{
id: 2,
depth: 3,
title: 'SubBookmark 22',
},
{
id: 3,
depth: 3,
title: 'SubBookmark 33',
subFolder: [
{
id: 1,
depth: 4,
title: 'SubBookmark 111',
},
],
},
],
},
{
id: 2,
depth: 2,
title: 'SubBookmark 2',
},
],
},
];
您的问题似乎是您只是在编辑当前单击的节点。您需要做的是在“selectFolderHandler”中重置所有其他项目的图像。
一种方法是遍历每个项目,并将图像设置为初始图像,然后更改当前选择的(由于性能不明智)。
建议的方法是找到一个打开的文件夹图像(如果存在)并重置它。最简单的是通过 class 或 ref 属性搜索。
想法是,当您 select 一个文件夹时,您应该从父组件 BookmarksFolder
中删除 select 其他文件夹。解决方案有点棘手,因为您 select 使用 BookmarksFolderNode
本地状态的文件夹(我的意思是 folderIsOpen
)。
好吧,让我们开始使用父组件的状态到 select/deselect 文件夹:
import BookmarksFolderNode from './BookmarksFolderNode';
import classes from './BookmarksFolder.module.css';
import { folders } from '../../resources/data';
function BookmarksFolder() {
const [foldersSelected, setFoldersSelected] = useState(new Array(folders.length).fill(false));
const selectFolder = (index) => {
let result = new Array(folders.length).fill(false);
result[index] = true;
setFoldersSelected(result);
}
return (
<div className={classes.bookmarksFolder}>
{folders.map((folder, index) => (
<BookmarksFolderNode
key={folder.id}
folder={folder}
isSelected={foldersSelected[index]}
select={(index) => selectFolder(index)}
index={index}
/>
))}
</div>
);
}
export default BookmarksFolder;
所以现在 BookmarksFolderNode
我们必须使用 isSelected
和 select
而不是 folderIsOpen
和 openFolderHandler
。不仅如此,我们还必须为子文件夹复制相同的逻辑:
import { useState, useRef, useEffect } from 'react';
import { AiFillCaretDown, AiFillCaretRight } from 'react-icons/ai';
import Folder from '../../resources/img/folder.svg';
import OpenedFolder from '../../resources/img/opened_folder.svg';
import classes from './BookmarksFolderNode.module.css';
function BookmarksFolderNode(props) {
const [subfoldersSelected, setSubFoldersSelected] = useState(new Array(props.folder.subFolder.length).fill(false));
const tab = useRef();
const img = useRef();
const title = useRef();
useEffect(() => {
if (props.isSelected) {
tab.current.style.backgroundColor = '#1a73eb';
img.current.src = OpenedFolder;
title.current.style.color = '#1a73eb';
}
else {
tab.current.style.backgroundColor = 'black';
img.current.src = Folder;
title.current.style.color = 'black';
}
}, [props.isSelected])
const openFolderHandler = () => {
props.select(props.index)
};
const paddingLeft = 20 * (props.folder.depth - 1);
const selectSubfolder = (index) => {
let result = new Array(props.folder.subFolder.length).fill(false);
result[index] = true;
setSubFoldersSelected(result);
}
return (
<div className={classes.bookmarksFolderNode}>
<div className={classes.bookmarksMainFolderNode}>
<div className={classes.verticalTab} ref={tab}></div>
<div className={classes.innerContainer} style={{paddingLeft}}>
<div className={classes.icon} onClick={openFolderHandler}>
{props.isSelected ? (
<AiFillCaretDown className={classes.ironIcon} />
) : (
<AiFillCaretRight className={classes.ironIcon} />
)}
</div>
<img src={Folder} className={classes.folderIcon} ref={img} />
<div
className={classes.menuLabel}
onClick={openFolderHandler}
ref={title}
>
{props.folder.title}
</div>
</div>
</div>
<div className={classes.bookmarksSubFolderNode}>
{props.folder.subFolder &&
props.folder.subFolder.map((subFolder, index) => (
<BookmarksFolderNode key={subFolder.id} folder={subFolder} index={index} isSelected={subfoldersSelected[index]} select={(index) => selectSubfolder(index)} />
))}
</div>
</div>
);
}
export default BookmarksFolderNode;
所以现在,如果您 select 一个文件夹(或子文件夹),其他文件夹(或子文件夹)将被删除select并且 useEffect
将应用所需的 css.