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

React中联动获取两个下拉框选中值实现货币转换

解决React货币转换器的下拉框值获取与转换问题

Hi Robert! 我看了你的代码和问题,其实你已经离解决问题很近了——根本不需要用refs,因为你已经把两个下拉框的汇率值存在组件的state里了(left和right字段),只要调整一下事件处理的逻辑,就能轻松完成货币转换计算。

核心问题分析

你当前的代码已经把左下拉框的汇率存在state.left,右下拉框的存在state.right,所以不管哪个下拉框变化,你都可以直接从this.state里拿到另一个下拉框的汇率值,直接进行除法运算就行。现在的小问题是右边下拉框的onChange事件没有传递完整的参数,还有输入框的结果显示逻辑可以优化。

具体修改步骤

  1. 补全右边下拉框的onChange参数
    右边的select组件在触发handleChange时,要和左边一样传递文本名称和文本值,这样state.righttext才能正确保存:

    <select onChange={e => this.handleChange('right', e.target.value, 'righttext', e.target.selectedOptions[0].text)}>
      {options}
    </select>
    
  2. 优化转换计算与结果显示
    把输入框的placeholder改成提示文本(比如"输入金额"),然后把转换后的结果显示在上方的<p>标签里,这样更直观。比如左边输入后,右边的金额是leftinput * right / left,反之亦然。

  3. 简化handleChange逻辑
    不管是下拉框切换还是输入框输入,只要state更新后,直接用当前的left、right、leftinput、rightinput计算转换结果就行,不需要额外的rightmultiply字段。

修改后的完整代码

import React, { Component } from 'react'; 
import "../../App.css" 
import cc from 'currency-codes' 

class Countries extends Component { 
  constructor() { 
    super(); 
    this.state = { 
      countryCodes: [], 
      left: '1.198', // 默认欧元兑美元汇率
      right: '1.198', 
      leftinput: '', 
      rightinput: '', 
      lefttext: 'US Dollar', // 默认左货币名称
      righttext: 'US Dollar' // 默认右货币名称
    }; 
  } 

  componentDidMount(){ 
    fetch('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml') 
      .then(response => response.text()) 
      .then(str => (new window.DOMParser()).parseFromString(str, "text/xml")) 
      .then(data => { 
        const countryCodes = []; 
        const cubes = data.getElementsByTagName("Cube") 
        for( const element of cubes) { 
          if (!element.getAttribute('currency')) { 
            continue; 
          } 
          countryCodes.push({ 
            currency: element.getAttribute('currency'), 
            rate: element.getAttribute('rate') 
          }); 
        } 
        // 初始化默认选中美元(如果数据里有)
        const usdRate = countryCodes.find(item => item.currency === 'USD')?.rate || '1.198';
        this.setState({
          countryCodes,
          left: usdRate,
          right: usdRate
        }); 
      }); 
  } 

  convertCurrCode(curr){ 
    const codeObject = cc.code(curr) 
    return codeObject?.currency || 'Unknown Currency' 
  } 

  handleChange(column, value, textname, text) { 
    // 更新对应的state字段
    const updateObj = { [column]: value };
    if (textname && text) {
      updateObj[textname] = text;
    }
    this.setState(updateObj, () => { 
      // 计算转换结果
      const leftToRight = this.state.leftinput ? (this.state.leftinput * this.state.right / this.state.left).toFixed(4) : '';
      const rightToLeft = this.state.rightinput ? (this.state.rightinput * this.state.left / this.state.right).toFixed(4) : '';
      
      console.log(`转换结果:${this.state.leftinput} ${this.state.lefttext} = ${leftToRight} ${this.state.righttext}`);
      console.log(`转换结果:${this.state.rightinput} ${this.state.righttext} = ${rightToLeft} ${this.state.lefttext}`);
    }); 
  } 

  render() { 
    const options = this.state.countryCodes.map( ({currency, rate}) => (
      <option key={currency} value={rate}>{this.convertCurrCode(currency)}</option>
    )); 

    // 实时计算转换结果
    const leftResult = this.state.leftinput ? (this.state.leftinput * this.state.right / this.state.left).toFixed(4) : '';
    const rightResult = this.state.rightinput ? (this.state.rightinput * this.state.left / this.state.right).toFixed(4) : '';

    return ( 
      <div> 
        <div className="App-column-left"> 
          <p>{this.state.leftinput || 0} {this.state.lefttext} = {leftResult || 0} {this.state.righttext}</p>
          <select onChange={e => this.handleChange('left', e.target.value, 'lefttext', e.target.selectedOptions[0].text)}>
            {options} 
          </select> 
          <input 
            type="text" 
            placeholder="输入金额" 
            value={this.state.leftinput}
            onChange={e => this.handleChange('leftinput', e.target.value)}
          /> 
        </div> 
        <div className="App-column-right"> 
          <p>{this.state.rightinput || 0} {this.state.righttext} = {rightResult || 0} {this.state.lefttext}</p>
          <select onChange={e => this.handleChange('right', e.target.value, 'righttext', e.target.selectedOptions[0].text)}>
            {options} 
          </select> 
          <input 
            type="text" 
            placeholder="输入金额" 
            value={this.state.rightinput}
            onChange={e => this.handleChange('rightinput', e.target.value)}
          /> 
        </div> 
      </div> 
    ) 
  } 
} 

export default Countries;

关键说明

  • 受控组件模式:所有输入类组件(select、input)的值都由state控制,这是React的推荐做法,比使用refs更可靠、更符合React的数据流理念。
  • 实时计算:每次state更新后,都会重新计算转换结果并显示在页面上,用户操作后能立即看到反馈。
  • 容错处理:在convertCurrCode里加了可选链操作符,避免找不到货币代码时报错;初始化时也做了默认值处理,防止数据加载前出现异常。

这样修改后,不管你切换哪个下拉框,或者在哪个输入框输入金额,都能正确获取两个下拉框的汇率值并完成转换计算啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:35:48