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

React输入框onChange触发时意外调用articles的useState问题求助

问题原因与解决方案

核心原因

React组件每次重新渲染时,组件函数会完整执行一遍,包括useState的初始值表达式。你在articles的useState初始值中直接调用了id.next(),所以每次组件因title/summary状态变化重新渲染时,这两个id.next()都会被执行,导致生成器不断推进,输出新的i值。

注意:useState的初始值只会在组件首次挂载时被用来初始化状态,但初始值表达式本身在每次渲染时都会执行——React会忽略首次挂载后的初始值,但表达式的执行是无法避免的。

修复方案

方案1:用useMemo缓存初始articles数组

把初始articles的创建逻辑包裹在useMemo中,依赖项设为空数组,确保只在组件首次渲染时执行一次:

import { useState, useCallback, useMemo } from 'react';

const id = (function* () {
    let i = 1;
    while (true) {
    console.log(i);
    yield i;
    i += 1;
    }
})();

function MyFeature() {
    // 用useMemo缓存初始数组,仅首次渲染执行
    const initialArticles = useMemo(() => [
        {
            id: id.next(),
            title: "Article 1",
            summary: "Article 1 summary",
            display: "none"
        },
        {
            id: id.next(),
            title: "Article 2",
            summary: "Article 2 summary",
            display: "none"
        }
    ], []);

    const [articles, setArticles] = useState(initialArticles);
    // ... 其余代码不变
}

方案2:直接初始化固定id(更简单)

如果初始文章的id不需要动态生成,直接写死固定值,仅在新增文章时调用生成器:

function MyFeature() {
    const [articles, setArticles] = useState([
        {
            id: { value: 1 }, // 直接写死初始id
            title: "Article 1",
            summary: "Article 1 summary",
            display: "none"
        },
        {
            id: { value: 2 },
            title: "Article 2",
            summary: "Article 2 summary",
            display: "none"
        }
    ]);
    // ... 新增时依然用id.next()
}

额外注意点

你的生成器id.next()返回的是IteratorResult对象(结构为{ value: 数字, done: 布尔值 }),在删除文章的逻辑中,onClickRemove里的判断article.id !== id其实是在比较对象引用,应该改为比较article.id.value !== id.value,否则删除功能会失效:

const onClickRemove = useCallback((id) => {
    setArticles((state) => state.filter((article) => article.id.value !== id.value));
}, []);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 11:57:40