Next.js中useMemo与useState同步异常问题求助
问题解决:语言切换时React State未同步翻译数据
问题原因
useState的初始值仅在组件首次挂载时读取一次,后续即使initialProjectsWL因语言切换更新,projectsWL这个state也不会自动同步变化。
解决方案
根据是否需要保留本地状态(比如isActive的用户操作),分两种处理方式:
1. 无需保留本地修改,直接同步翻译数据
添加useEffect监听initialProjectsWL的变化,一旦更新就同步到state:
const initialProjectsWL: ProjectWL[] = useMemo(() => { const arr: ProjectWLDraft[] = t('whiteLabel.projects', {returnObjects: true}) const newArr: ProjectWL[] = arr.map((el, idx) => ({ ...el, isActive: false, className: `project-${idx}` })) return newArr; }, [t]) const [projectsWL, setProjectsWl] = useState(initialProjectsWL); // 监听翻译数据变化,同步更新state useEffect(() => { setProjectsWl(initialProjectsWL); }, [initialProjectsWL])
2. 需要保留用户操作的状态(如isActive)
更新时合并原有项目的状态,确保用户之前的选择不会丢失(假设项目有唯一id字段):
const [projectsWL, setProjectsWl] = useState<ProjectWL[]>(() => { // 首次初始化时生成初始数据 const arr = t('whiteLabel.projects', {returnObjects: true}) as ProjectWLDraft[]; return arr.map((el, idx) => ({ ...el, isActive: false, className: `project-${idx}` })); }); // 语言切换时更新翻译内容,保留isActive状态 useEffect(() => { const updatedProjects = (t('whiteLabel.projects', {returnObjects: true}) as ProjectWLDraft[]).map((el, idx) => { const existing = projectsWL.find(p => p.id === el.id); return { ...el, isActive: existing?.isActive ?? false, className: `project-${idx}` }; }); setProjectsWl(updatedProjects); }, [t, projectsWL])
说明
- 第一种方案简单直接,适合不需要用户修改状态的场景;
- 第二种方案通过匹配项目唯一标识,保留用户操作过的
isActive状态,更符合交互需求。
内容的提问来源于stack exchange,提问作者Meirbek Ordaly
相关产品推荐
相关产品推荐

