当我在 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 我们必须使用 isSelectedselect 而不是 folderIsOpenopenFolderHandler。不仅如此,我们还必须为子文件夹复制相同的逻辑:

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.