面试遇到的小问题

78 阅读2分钟

1.usecontext和redux有啥缺陷

useContext 本质只是 跨组件传值,并不是真正的“状态管理库”。

缺点:

  1. 更新粒度粗

    • Provider 里的 value 变化时,所有用到 useContext 的子组件都会重新渲染,即使只依赖其中的一小部分数据。
    • 可能导致 性能浪费
    const ThemeContext = createContext();
    
    function App() {
      const [theme, setTheme] = useState("light");
      return (
        <ThemeContext.Provider value={{ theme, setTheme }}>
          <Child1 />  {/* 也会重渲染 */}
          <Child2 />  {/* 也会重渲染 */}
        </ThemeContext.Provider>
      );
    }
    
  2. 缺少中间件/调试工具

    • useContext 没有像 Redux 那样的 devtools、时间旅行、日志、异步中间件。
    • 不适合管理复杂业务逻辑。
  3. 难以拆分模块

    • 如果全局状态多了,要建很多 Context,嵌套 Provider 会变成 “Provider Hell”。

Redux的缺陷

Redux 是一个完整的状态管理库,功能强大,但也有缺陷:

  1. 样板代码多

    • Redux 早期需要写 action、reducer、dispatch,很冗余。
    • 虽然现在有 Redux Toolkit 缓解了很多,但相比 Context 还是复杂。
  2. 学习成本高

    • 新人要理解 reducer、纯函数、不可变数据、middleware 等一套概念。
  3. 过度抽象

    • 对于小项目,用 Redux 显得“杀鸡用牛刀”,维护成本大于收益。
  4. 性能问题

    • 默认 connect 或 useSelector 如果写不好(没加浅比较),也会导致全局更新过多。
    • 虽然可以优化(分 slice、memo、reselect),但要开发者有经验。 Redux 的缺陷

Redux 是一个完整的状态管理库,功能强大,但也有缺陷:

  1. 样板代码多

    • Redux 早期需要写 action、reducer、dispatch,很冗余。
    • 虽然现在有 Redux Toolkit 缓解了很多,但相比 Context 还是复杂。
  2. 学习成本高

    • 新人要理解 reducer、纯函数、不可变数据、middleware 等一套概念。
  3. 过度抽象

    • 对于小项目,用 Redux 显得“杀鸡用牛刀”,维护成本大于收益。
  4. 性能问题

    • 默认 connect 或 useSelector 如果写不好(没加浅比较),也会导致全局更新过多。
    • 虽然可以优化(分 slice、memo、reselect),但要开发者有经验。

🔹实现瀑布流的常见方案

1. 纯 CSS 实现(简单但受限)

利用 CSS 列布局(column-count / column-width)

<div class="waterfall">
  <div class="item">内容1</div>
  <div class="item">内容2</div>
  <div class="item">内容3</div>
  <div class="item">内容4</div>
  ...
</div>
.waterfall {
  column-count: 4;     /* 列数 */
  column-gap: 16px;    /* 列间距 */
}

.item {
  break-inside: avoid; /* 避免被拆开 */
  margin-bottom: 16px;
  background: #f2f2f2;
  border-radius: 8px;
  padding: 10px;
}

✅ 优点:简单,代码量少
❌ 缺点:列高无法均衡(某一列可能比其他列长很多),无法精细控制


2. CSS Grid 实现(现代浏览器)

利用 grid-auto-rows + grid-row-end: span 实现近似瀑布流:

.waterfall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: 10px; /* 基础行高 */
  gap: 16px;
}

.item {
  background: #f2f2f2;
  border-radius: 8px;
  padding: 10px;
}

/* JS 动态计算 span 的行数 */

需要用 JS 计算 grid-row-end: span 的值,= item高度 / grid-auto-rows

✅ 优点:布局可控,现代化方案
❌ 缺点:需要 JS 配合