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

React函数组件状态变更时DOM不更新问题求助

问题原因

你当前的问题是CTA和LanguageButtons组件各自维护了独立的isEnglish状态:虽然两个组件都从localStorage读取同一份数据,但它们的state是完全分开的。当LanguageButtons调用setEnglish更新localStorage时,CTA组件里的isEnglish state并不会自动刷新——因为你写的useLocalStorage钩子只在组件初始化时读取一次localStorage,之后不会监听localStorage的变化。


方案一:状态提升(最简单,适合新手)

把语言状态提到父组件(App.js),通过props传递给子组件,让两个组件共享同一个状态,状态变化时所有依赖组件都会自动更新。

修改步骤:

  1. App.js:把useLocalStorage的状态放在这里,作为全局共享状态
import './App.css';
import CTA from './components/CTA';
import useLocalStorage from './util/store';

function App() {
  const [isEnglish, setIsEnglish] = useLocalStorage('isEnglish', true);
  
  return (
    <div className="App">
        <CTA isEnglish={isEnglish} setIsEnglish={setIsEnglish} />
    </div>
  );
}

export default App;
  1. CTA.js:不再自己调用useLocalStorage,直接接收父组件传递的状态
import * as React from 'react';
import CTA_Image from '../assets/cibc-event.jpeg'
import styles from '../styles/language.module.css'
import LanguageButtons from './LanguageButtons'

export default function CTA({ isEnglish, setIsEnglish }) {
  React.useEffect(() => {
      console.log(isEnglish)
  }, [isEnglish])

  console.log(isEnglish)
  return (
      <>
          <img src={CTA_Image} className={styles.ctaImage} alt='' />

          {isEnglish === true ? 
              <p className={styles.ctaBody}>
                  English, i am english, yes
              </p>
          :   <p className={styles.ctaBody}>
                  French, parle french, oui
              </p>
          }

          <LanguageButtons setIsEnglish={setIsEnglish} />
      </>
  )
}
  1. LanguageButtons.js:同样接收父组件的setIsEnglish,不再自己维护状态
import { Button } from "@mui/material"
import styles from '../styles/language.module.css'

const LanguageButtons = ({ setIsEnglish }) => {
    let handleLanguage = (value) => {
        setIsEnglish(value)
    }
    return (
        <>
            <Button variant="contained" className={styles.languageButton} onClick={()=>handleLanguage(true)}>English</Button>
            <Button variant="contained" className={styles.languageButton} onClick={()=>handleLanguage(false)}>French</Button>
        </>
    )
}

export default LanguageButtons

方案二:改进useLocalStorage钩子(通用型,适合多组件共享)

如果后续有更多组件需要用到语言状态,不想每次都传props,可以修改useLocalStorage钩子,让它监听storage事件,自动同步localStorage的变化。

修改store.js:

import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
    const [storedValue, setStoredValue] = useState(() => {
        if (typeof window === "undefined") {
            return initialValue;
        }
        try {
            const item = window.localStorage.getItem(key);
            return item ? JSON.parse(item) : initialValue;
        } catch (error) {
            console.log(error);
            return initialValue;
        }
    });

    // 监听storage事件,同步其他组件/标签页修改的localStorage值
    useEffect(() => {
        const handleStorageChange = (e) => {
            if (e.key === key) {
                try {
                    setStoredValue(e.newValue ? JSON.parse(e.newValue) : initialValue);
                } catch (error) {
                    console.log(error);
                    setStoredValue(initialValue);
                }
            }
        };

        window.addEventListener('storage', handleStorageChange);
        return () => window.removeEventListener('storage', handleStorageChange);
    }, [key, initialValue]);

    const setValue = (value) => {
        try {
            const valueToStore = value instanceof Function ? value(storedValue) : value;
            setStoredValue(valueToStore);
            if (typeof window !== "undefined") {
                window.localStorage.setItem(key, JSON.stringify(valueToStore));
                // 手动触发storage事件(同一标签页修改localStorage不会自动触发)
                window.dispatchEvent(new StorageEvent('storage', {
                    key: key,
                    newValue: JSON.stringify(valueToStore)
                }));
            }
        } catch (error) {
            console.log(error);
        }
    };

    return [storedValue, setValue];
}

export default useLocalStorage;

修改后,你原来的CTA和LanguageButtons组件不需要做任何改动,就能实现状态同步更新。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:20:31