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

React侧边栏过滤器状态优化:解决代码臃肿且保留原有功能

优化过滤器侧边栏状态管理与代码精简方案

1. 合并过滤器展开状态,减少重复useState

把多个分散的过滤器展开状态合并为一个对象,用单个useState管理,同时编写通用的状态切换函数,避免重复定义setFilterXOpen:

const [filterExpansions, setFilterExpansions] = useState({
  filterOne: false,
  filterTwo: false,
  filterThree: false,
  filterFour: false
});

const toggleFilterExpansion = (filterKey) => {
  setFilterExpansions(prev => ({
    ...prev,
    [filterKey]: !prev[filterKey]
  }));
};

2. 抽离侧边栏渲染逻辑,消除重复代码

将两次渲染FiltersSideBar的逻辑封装成一个函数,避免重复编写props和条件判断:

const renderFiltersSidebar = (className = "") => (
  <FiltersSideBar
    className={className}
    filterExpansions={filterExpansions}
    toggleFilterExpansion={toggleFilterExpansion}
  />
);

之后在JSX中直接调用该函数即可:

{size.width > 600 && renderFiltersSidebar()}
{size.width <= 600 && !hideSidebar && renderFiltersSidebar("overlay")}

3. 将过滤器状态移入Context,彻底取消props传递

利用已有的AppContext,把过滤器的展开状态和切换函数加入Context的value中:

<AppContext.Provider value={{ 
  filters, 
  setFilters,
  filterExpansions,
  toggleFilterExpansion
}}>

在FiltersSideBar组件内直接通过useContext获取状态和方法,无需再接收大量props:

// FiltersSideBar.js
import { useContext } from 'react';
import AppContext from './AppContext';

const FiltersSideBar = ({ className = "" }) => {
  const { filterExpansions, toggleFilterExpansion } = useContext(AppContext);
  
  // 使用示例:filterExpansions.filterOne 就是原filterOneOpen的状态
  // 切换示例:toggleFilterExpansion('filterOne')
  
  return (
    // 侧边栏原有内容
  );
};

完整修改后的App.js代码

export default function App() {
  const [hideSidebar, setHideSidebar] = useState(true);
  
  // 合并过滤器展开状态
  const [filterExpansions, setFilterExpansions] = useState({
    filterOne: false,
    filterTwo: false,
    filterThree: false,
    filterFour: false
  });

  // 通用切换函数
  const toggleFilterExpansion = (filterKey) => {
    setFilterExpansions(prev => ({
      ...prev,
      [filterKey]: !prev[filterKey]
    }));
  };

  // 抽离侧边栏渲染逻辑
  const renderFiltersSidebar = (className = "") => (
    <FiltersSideBar className={className} />
  );

  return (
    <ThemeProvider theme={theme}>
      <BrowserRouter>
        <AppContext.Provider value={{ 
          filters, 
          setFilters,
          filterExpansions,
          toggleFilterExpansion
        }}>
          <div style={{display: 'flex', backgroundColor: '#f6f7f9'}}>
            <button 
              className="overlay-button-hidden"
              style={{display: size.width > 600 ? "none" : "inline"}}
              onClick={() => setHideSidebar(prev => !prev)}
            >
              <ArrowBackIosNewIcon />
            </button>
          
            {size.width > 600 && renderFiltersSidebar()}

            <div style={{ display: "flex" }}>
              {size.width <= 600 && !hideSidebar && renderFiltersSidebar("overlay")}
              
              {size.width <= 600 && !hideSidebar && (
                <button 
                  className="overlay-button"
                  style={{display: size.width > 600 ? "none" : "inline"}}
                  onClick={() => setHideSidebar(prev => !prev)}
                >
                  <ArrowBackIosNewIcon />
                </button>
              )}
            </div>
            
            <Routes>
              <Route path="*" element={<Navigate to="/devices" replace />} />
            </Routes>
          </div>
        </AppContext.Provider>
      </BrowserRouter>
    </ThemeProvider>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:18:24