You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中点击某一项时,如何为当前项应用新样式并为其余项恢复原有样式?

Fixing Single Selection for Bookmark Folders

Got it, let's fix this single-selection issue! The problem right now is that each BookmarksFolderNode is handling its own selection state independently—so when you click one, others don't know to reset their styles. Here's how to fix it using React's state lifting pattern, which is perfect for this kind of shared state scenario:

Step 1: Lift Selection State to Parent Component (BookmarksFolder.js)

We'll move the selection state to the parent component so it can act as a single source of truth for all child nodes.

import BookmarksFolderNode from './BookmarksFolderNode';
import classes from './BookmarksFolder.module.css';
import { folders } from '../../resources/data';
import { useState } from 'react';

function BookmarksFolder() {
  // Track the ID of the currently selected folder
  const [selectedFolderId, setSelectedFolderId] = useState(null);

  // Handle selection events from child nodes
  const handleFolderSelect = (folderId) => {
    setSelectedFolderId(folderId);
  };

  return (
    <div className={classes.bookmarksFolder}>
      {folders.map((folder) => (
        <BookmarksFolderNode 
          key={folder.id} 
          folder={folder} 
          selectedId={selectedFolderId}
          onSelect={handleFolderSelect}
        />
      ))}
    </div>
  );
}
export default BookmarksFolder;

Step 2: Update Child Component to Use Props-Driven Styles (BookmarksFolderNode.js)

We'll remove direct DOM manipulation (an anti-pattern in React) and instead use props to conditionally apply styles. We'll also pass the selection state down to nested subfolders.

import { useState } 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 openFolderHandler = () => {
    setFolderIsOpen((prevState) => !prevState);
  };

  // Check if current folder is the selected one
  const isSelected = props.folder.id === props.selectedId;

  // Trigger parent's selection handler on click
  const selectFolderHandler = () => {
    props.onSelect(props.folder.id);
  };

  const paddingLeft = 20 * (props.folder.depth - 1);
  return (
    <div className={classes.bookmarksFolderNode}>
      <div className={classes.bookmarksMainFolderNode}>
        {/* Conditional style for vertical tab */}
        <div 
          className={`${classes.verticalTab} ${isSelected ? classes.selectedTab : ''}`}
        ></div>
        <div className={classes.innerContainer} style={{paddingLeft}}>
          <div className={classes.icon} onClick={openFolderHandler}>
            {folderIsOpen ? (
              <AiFillCaretDown className={classes.ironIcon} />
            ) : (
              <AiFillCaretRight className={classes.ironIcon} />
            )}
          </div>
          {/* Conditional folder icon based on selection */}
          <img 
            src={isSelected ? OpenedFolder : Folder} 
            className={classes.folderIcon} 
          />
          {/* Conditional style for folder title */}
          <div 
            className={`${classes.menuLabel} ${isSelected ? classes.selectedLabel : ''}`}
            onClick={selectFolderHandler}
          >
            {props.folder.title}
          </div>
        </div>
      </div>
      <div className={classes.bookmarksSubFolderNode}>
        {props.folder.subFolder && props.folder.subFolder.map((subFolder) => (
          <BookmarksFolderNode 
            key={subFolder.id} 
            folder={subFolder} 
            selectedId={props.selectedId}
            onSelect={props.onSelect}
          />
        ))}
      </div>
    </div>
  );
}
export default BookmarksFolderNode;

Step 3: Add Selected State Styles to CSS (BookmarksFolderNode.module.css)

Replace direct style manipulations with CSS classes for cleaner, more maintainable code:

/* Add these classes to your existing CSS */
.selectedTab {
  background-color: #1a73eb;
}

.selectedLabel {
  color: #1a73eb;
}

Why This Works

  • Single Source of Truth: The parent component controls which folder is selected, ensuring only one folder can be active at a time.
  • Props-Driven Rendering: Styles are applied based on prop values, which aligns with React's declarative programming model (no more manual DOM tweaks).
  • Recursive Support: Selection state and handlers are passed down to nested subfolders, so the single-selection behavior works across all levels of your folder hierarchy.

内容的提问来源于stack exchange,提问作者Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 11:07:47