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
相关产品推荐
相关产品推荐

