如何在非父子组件间传递useState的lang值,实现背景模糊效果
非父子组件共享状态实现背景模糊效果
首先纠正你样式代码的语法错误:
你写的代码存在属性名错误(styles应改为style)、括号不配对、拼写错误(backgroun改为backgroundColor),简化后的正确写法:
style={lang === 2 ? { filter: 'blur(10px)' } : { backgroundColor: '#F4F4F4' }}
另外你的openLang函数逻辑可以优化,直接依赖前一次状态更新更稳妥:
const openLang = () => { setLang(prev => prev + 1); };
针对非父子组件共享lang状态的问题,提供三种实用方案:
1. 状态提升(最简方案,适合小型项目)
把lang状态和更新逻辑提到两个组件的共同父组件中,通过props传递给需要的组件:
// 共同父组件 import { useState } from 'react'; import LanguageSlider from './LanguageSlider'; import TargetComponent from './TargetComponent'; function Parent() { const [lang, setLang] = useState(1); const openLang = () => { setLang(prev => prev + 1); }; return ( <div> <LanguageSlider openLang={openLang} /> <TargetComponent lang={lang} /> </div> ); } // LanguageSlider组件 function LanguageSlider({ openLang }) { return ( <div onClick={openLang}> {/* 语言切换滑块内容 */} </div> ); } // 需要背景模糊的目标组件 function TargetComponent({ lang }) { return ( <div style={lang === 2 ? { filter: 'blur(10px)' } : { backgroundColor: '#F4F4F4' }} > {/* 目标组件内容 */} </div> ); }
2. React Context(适合跨多层组件共享)
如果组件层级较深,props传递繁琐,可以用Context封装状态,所有子组件都能直接获取:
// 创建LangContext import { createContext, useState, useContext } from 'react'; const LangContext = createContext(); // Context提供者组件 function LangProvider({ children }) { const [lang, setLang] = useState(1); const openLang = () => { setLang(prev => prev + 1); }; return ( <LangContext.Provider value={{ lang, openLang }}> {children} </LangContext.Provider> ); } // 在App中包裹所有需要共享状态的组件 function App() { return ( <LangProvider> <LanguageSlider /> <TargetComponent /> </LangProvider> ); } // LanguageSlider组件使用Context function LanguageSlider() { const { openLang } = useContext(LangContext); return ( <div onClick={openLang}> {/* 滑块内容 */} </div> ); } // 目标组件使用Context function TargetComponent() { const { lang } = useContext(LangContext); return ( <div style={lang === 2 ? { filter: 'blur(10px)' } : { backgroundColor: '#F4F4F4' }} > {/* 目标内容 */} </div> ); }
3. 状态管理库(比如Redux Toolkit,适合大型应用)
如果项目有大量全局状态需要管理,用Redux这类库更规范:
// 定义lang切片 import { createSlice } from '@reduxjs/toolkit'; const langSlice = createSlice({ name: 'lang', initialState: { value: 1 }, reducers: { incrementLang: (state) => { state.value += 1; }, }, }); export const { incrementLang } = langSlice.actions; export default langSlice.reducer; // 创建store import { configureStore } from '@reduxjs/toolkit'; import langReducer from './langSlice'; export const store = configureStore({ reducer: { lang: langReducer }, }); // 全局包裹Provider import { Provider } from 'react-redux'; import { store } from './store'; function App() { return ( <Provider store={store}> <LanguageSlider /> <TargetComponent /> </Provider> ); } // LanguageSlider组件 import { useDispatch } from 'react-redux'; import { incrementLang } from './langSlice'; function LanguageSlider() { const dispatch = useDispatch(); return ( <div onClick={() => dispatch(incrementLang())}> {/* 滑块内容 */} </div> ); } // 目标组件 import { useSelector } from 'react-redux'; function TargetComponent() { const lang = useSelector(state => state.lang.value); return ( <div style={lang === 2 ? { filter: 'blur(10px)' } : { backgroundColor: '#F4F4F4' }} > {/* 目标内容 */} </div> ); }
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

