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

React实现两个输入框值双向联动更新的问题

问题描述

我用React的useState管理DataOne、DataTwo和focused状态,想实现修改一个输入框时,另一个按1:2的比例自动更新,后续还要对接汇率API填充对应值。但现在联动逻辑混乱,效果不可控,试了多种value绑定都没用,怎么实现输入框的双向联动更新?

原代码:

const [DataOne, setDataOne] = useState(null);
const [DataTwo, setDataTwo] = useState(null);
const [focused, setFocused] = useState(false);

function getValueOne(val) {
    setDataOne(val.target.value)
    console.log(val.target.value);
}
function getValueTwo(val) {
    setDataTwo(val.target.value)
    console.log(val.target.value);
}
const onFocus = () => setFocused(true);

return (
    <div>
        <div>
            <select>
                <option value={0}>Currency to send:</option>
                <option value={1}>Dollar</option>
                <option value={2}>Euro</option>
                <option value={3}>Pound</option>
            </select>
        </div>
        <div>
            <select>
                <option value={0}>Currency to receive:</option>
                <option value={1}>Dollar</option>
                <option value={2}>Euro</option>
                <option value={3}>Pound</option>
            </select>
        </div>
        <div>
            <input 
                type={'number'} 
                placeholder={'Fruit in'} 
                onChange={getValueOne} 
                value={DataTwo === null ? 0 :  (focused ? DataTwo / 2 : DataOne)}
                onFocus={onFocus}
            ></input>
        </div>
        <div>
            <input 
                type={'number'} 
                placeholder={'Fruit out'}
                onChange={getValueTwo} 
                value={DataOne === null ? 0 : (focused ? DataOne / 2 : DataTwo)}
            ></input>
        </div>
    </div>
)
解决方案

你的问题核心是用布尔值记录focused状态无法区分哪个输入框在编辑,导致value绑定逻辑混乱。改成跟踪具体激活的输入框,同时让非激活输入框的值通过计算生成,就能解决联动问题:

关键调整点

  • 把focused从布尔值改成字符串,记录当前聚焦的输入框(比如'inputOne'或'inputTwo')
  • 输入框的value规则:自己处于激活状态时用自身的state值,否则用另一个输入框的值按比例转换
  • 输入事件只更新当前输入框对应的state,不需要手动更新另一个,避免循环触发

修改后的完整代码

import { useState } from 'react';

function CurrencyConverter() {
    // 初始值设为0,避免null导致的显示异常
    const [dataOne, setDataOne] = useState(0);
    const [dataTwo, setDataTwo] = useState(0);
    // 记录当前聚焦的输入框,初始为空
    const [focusedInput, setFocusedInput] = useState('');
    // 先写死1:2的比例,后续替换成API获取的汇率即可
    const exchangeRate = 2; // 规则:dataTwo = dataOne * exchangeRate

    const handleInputOneChange = (e) => {
        // 转成数字,避免输入非数字内容导致异常
        const value = Number(e.target.value) || 0;
        setDataOne(value);
    };

    const handleInputTwoChange = (e) => {
        const value = Number(e.target.value) || 0;
        setDataTwo(value);
    };

    return (
        <div>
            <div>
                <select>
                    <option value={0}>Currency to send:</option>
                    <option value={1}>Dollar</option>
                    <option value={2}>Euro</option>
                    <option value={3}>Pound</option>
                </select>
            </div>
            <div>
                <select>
                    <option value={0}>Currency to receive:</option>
                    <option value={1}>Dollar</option>
                    <option value={2}>Euro</option>
                    <option value={3}>Pound</option>
                </select>
            </div>
            <div>
                <input 
                    type="number" 
                    placeholder="Fruit in" 
                    onChange={handleInputOneChange} 
                    // 激活时用自身state,非激活时同步对方的转换值
                    value={focusedInput === 'inputOne' ? dataOne : (dataTwo / exchangeRate)}
                    onFocus={() => setFocusedInput('inputOne')}
                    // 失焦后可选清空标记,让两个输入框保持同步
                    onBlur={() => setFocusedInput('')}
                />
            </div>
            <div>
                <input 
                    type="number" 
                    placeholder="Fruit out"
                    onChange={handleInputTwoChange} 
                    value={focusedInput === 'inputTwo' ? dataTwo : (dataOne * exchangeRate)}
                    onFocus={() => setFocusedInput('inputTwo')}
                    onBlur={() => setFocusedInput('')}
                />
            </div>
        </div>
    );
}

export default CurrencyConverter;

后续对接汇率API的扩展思路

  1. 新增状态存储实时汇率:const [exchangeRate, setExchangeRate] = useState(2);
  2. 在组件挂载或货币选择变化时,调用汇率API获取最新汇率,更新exchangeRate状态
  3. 转换逻辑直接使用exchangeRate代替硬编码的2,联动逻辑无需改动

原代码失效原因

之前用布尔值focused无法区分激活的输入框,导致两个输入框的value绑定逻辑冲突,输入时出现状态循环覆盖的问题。改成跟踪具体输入框后,每个输入框的显示逻辑清晰,激活时用自身编辑值,非激活时自动同步对方的转换值,不会出现混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:17:32