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

Next.js中React状态通过Props初始化后不随新Props更新的问题

问题:React Query加载完成后组件本地爱好列表状态未更新

场景复现

在Next.js项目中使用TanStack React Query实现骨架加载,数据加载完成后,name字段正常更新,但hobbies本地状态始终保持初始的空数组,只有页面跳转后返回才会加载新数据。

父组件加载逻辑代码:

if (isPending) {
    return <MyComponent
        name="Loading...."
        hobbies={[]}
    />
}

return <MyComponent name={data.name} hobbies={data.hobbies} />

子组件MyComponent代码:

function onSubmit() { /* 提交到服务器的逻辑 */ }

function MyComponent(props) {
    const [hobbies, setHobbies] = useState(props.hobbies);
    
    return (
        <form>
           <h1>{props.name}</h1>
           <MyList hobbies={hobbies} />
           <div>
               <input />
               <button type="button" onClick={() => {}}>add</button>
           </div>
           <button onClick={onSubmit}>submit</button>
        </form>
    )
}

问题原因

useState的初始值仅在组件首次挂载时生效,当父组件传递的props.hobbies更新时,子组件的本地hobbies状态不会自动同步——useState本身不会监听props的变化。

解决方案

通过useEffect监听props.hobbies的变化,当props更新时同步更新本地状态,同时可根据业务需求避免覆盖用户已做的本地修改。

修改后的MyComponent代码:

function onSubmit() { /* 提交到服务器的逻辑 */ }

function MyComponent(props) {
    const [hobbies, setHobbies] = useState(props.hobbies);
    // 标记是否有用户本地修改
    const [hasLocalChanges, setHasLocalChanges] = useState(false);
    
    // 仅在无本地修改时,同步服务器返回的新数据
    useEffect(() => {
        if (!hasLocalChanges) {
            setHobbies(props.hobbies);
        }
    }, [props.hobbies, hasLocalChanges]);

    // 处理添加爱好的逻辑,同时标记已有本地修改
    const handleAddHobby = () => {
        setHobbies(prev => [...prev, '新爱好']);
        setHasLocalChanges(true);
    }

    // 提交后重置本地修改标记
    const handleSubmit = () => {
        onSubmit(hobbies);
        setHasLocalChanges(false);
    }
    
    return (
        <form>
           <h1>{props.name}</h1>
           <MyList hobbies={hobbies} />
           <div>
               <input />
               <button type="button" onClick={handleAddHobby}>add</button>
           </div>
           <button onClick={handleSubmit}>submit</button>
        </form>
    )
}

简化版(无需区分本地修改场景)

如果业务上允许服务器数据覆盖所有本地未提交的修改,可直接去掉本地修改标记逻辑:

function MyComponent(props) {
    const [hobbies, setHobbies] = useState(props.hobbies);
    
    useEffect(() => {
        setHobbies(props.hobbies);
    }, [props.hobbies]);
    
    // 其他逻辑保持不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 13:03:12