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

React组件console.log打印状态重复输出两次的原因及修复方法

问题原因

控制台重复输出筛选值是React 18及以上版本开发环境默认开启严格模式(StrictMode)的预期行为,不属于业务逻辑bug:

  • 严格模式会在开发阶段对组件渲染阶段逻辑执行双调用,即重复走一次组件渲染、卸载、重挂载的流程,作用是提前检测不符合React规范的隐式副作用代码,提前暴露写法问题。
  • 你将console.log(filters)直接写在组件函数体顶层,属于渲染阶段同步执行的逻辑,自然会在严格模式的双渲染流程中被执行两次。
  • 该双执行行为仅在开发环境生效,生产环境构建后会自动消除,不会影响线上功能。

另外当前代码的筛选状态更新逻辑存在隐藏缺陷:setFilters现在的写法会直接用新值覆盖整个filters对象,后续如果新增尺寸、价格区间等其他筛选维度,之前选中的颜色值会被直接清空。

修正方案
  • 针对控制台双打印问题:不推荐关闭严格模式,其双检测机制可以帮你提前规避很多React写法隐患,生产环境下双打印会自动消失,无需特殊处理。如果开发环境调试时需要减少重复日志,可以将打印逻辑移入useEffect回调中,作为状态变化的明确副作用执行。
  • 针对筛选状态覆盖问题:改用函数式状态更新,合并旧状态的所有筛选字段,避免其他筛选项被覆盖。

修正后的完整组件代码:

import { useState, useEffect } from 'react';

const ProductList = () => {
  const [filters, setFilters] = useState({});
  const handleFilters = (e) => {
    const value = e.target.value;
    const name = e.target.name;
    // 函数式更新,合并历史筛选状态,避免覆盖其他筛选项
    setFilters(prev => ({
      ...prev,
      [name]: value,
    }));
  };

  // 状态变化后执行打印,明确副作用边界
  useEffect(() => {
    console.log(filters);
  }, [filters]);
   
  return (
    <Container>
      <Announcement />
      <Navbar />
      <Title>Dresses</Title>
      <FilterContainer>
        <Filter>
          <FilterText>Filter Products:</FilterText>
          <Select name="color" onChange={handleFilters}>
            <Option disabled>color</Option>
            <Option>white</Option>
            <Option>black</Option>
            <Option>red</Option>
            <Option>pink</Option>
            <Option>brown</Option>
            <Option>green</Option>
            <Option>milk</Option>
          </Select>
        </Filter>
      </FilterContainer>
      <Products />
      <Newsletter />
      <Footer />
    </Container>
  );
};
export default ProductList;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:36:08