React跨组件共享货币选择状态实现选中值同步方案
问题原因
你遇到的currencyState is not defined报错,是违反React状态作用域规则导致的:组件内部通过useState定义的状态属于组件私有状态,仅能在当前组件内部访问,兄弟组件、子组件都无法直接读取或修改。
实现方案:状态提升
React中兄弟组件共享状态的标准实现方式是状态提升:将需要共享的状态迁移到两个组件的最近公共父组件中维护,再通过props将状态值、状态更新方法分别下发给需要使用的子组件即可,具体实现分三步:
- 第一步:在公共父组件维护共享状态
找到同时引入渲染Currency和Bogota的父组件(一般是页面级组件,比如App.jsx),把原本定义在Currency内部的货币状态移到此处:
// 公共父组件示例 App.jsx import { useState } from 'react'; import Currency from './Currency'; import Bogota from './Bogota'; function App() { // 共享货币状态,可自行设置默认选中值 const [currencyState, setCurrencyState] = useState("USA"); return ( <div> {/* 页头区域:给选择器传入状态更新方法 */} <header> <Currency onCurrencyChange={setCurrencyState} /> </header> {/* 内容区域:给列表组件传入当前选中的货币值 */} <main> <Bogota currentCurrency={currencyState} /> </main> </div> ) } export default App;
- 第二步:改造Currency组件
删除组件内部原本的私有状态定义,下拉选择变化时调用父组件传入的更新方法修改共享状态:
// 改造后 Currency.jsx function Currency (props) { return ( <div> <select className="custom-select" onChange={(e) => { const selectedCountry = e.target.value; // 调用父组件传入的方法更新全局共享状态 props.onCurrencyChange(selectedCountry); }}> <option value="COP">COP</option> <option value="USA">USA</option> <option value="EUR">EUR</option> </select> </div> ); } export default Currency;
- 第三步:改造Bogota组件
删除原来直接引用currencyState的错误写法,从props中读取父组件下发的当前货币值,渲染到对应位置即可:
// 改造后 Bogota.jsx import React from 'react'; import './bogota.css'; function Bogota (props) { return ( <div className="skill__wrapper"> <table className='table'> <thead> <tr> <th>Dates</th> <th>Concert</th> <th>Singer</th> <th>Location</th> </tr> </thead> <tbody> <tr> <td>May 19th 2022</td> <td> <span className='country__currency'>{props.currentCurrency}</span> $80 + 10 </td> <td>Harry Styles</td> <td>Movistar Arena</td> <td><button className='btns'>Buy</button></td> </tr> <tr> <td>May 31st oct 2022</td> <td><span className='country__currency'>{props.currentCurrency}</span> $50 + 10</td> <td>Dua Lipa</td> <td>Movistar Arena</td> <td><button className='btns'>Buy</button></td> </tr> <tr> <td>Nov 20st 2022</td> <td><span className='country__currency'>{props.currentCurrency}</span> $100 + $20</td> <td>Motomami</td> <td>Movistar Arena</td> <td><button className='btns'>Buy</button></td> </tr> </tbody> </table> </div> ); }; export default Bogota;
补充说明:如果后续多层级、多页面都需要用到这个货币状态,逐层传props会比较繁琐,可以搭配React Context或者轻量状态管理库(如Zustand)做全局状态托管。但当前兄弟组件传值的场景,状态提升是最轻量、完全符合React设计规范的实现方式。
内容的提问来源于stack exchange,提问作者Ricardo Sánchez
相关产品推荐
相关产品推荐

