提问人:albertoivo 提问时间:10/25/2023 最后编辑:T.J. Crowderalbertoivo 更新时间:10/25/2023 访问量:46
使用 React 更改输入并折射其他几个输入上的更改
Change an input and reflact change on several other inputs with React
问:
我有 19 个输入,当其中一个输入发生变化时,所有其他输入都会通过计算反映变化。
<input value={mph} onChange={(e) => cmph(e.target.value, setKph, setMps)}
<input value={kph} onChange={(e) => ckph(e.target.value, setMph, setMps)}
<input value={mps} onChange={(e) => cmps(e.target.value, setKph, setMph)}
对于每个输入,我都有一个状态。所以我使用了 19 个变量。并且所有输入都有一个 .useState
onChange
const [mph, setMph] = useState() // miles per hour
const [kph, setKph] = useState() // kiliometers per hour
const [mps, setMps] = useState() // miles per seconds
因此,当任何输入发生更改时,它会调用其唯一函数进行计算并设置状态 18 次(对于其他每个输入)。onChange
每个输入都调用自己的函数来计算其他输入的值。它简单的数学。没有数据库或终端节点调用。
function cmph(mph, setKph, setMps) {
const kph = mph * 1.60934
setKph(Math.round((kph + Number.EPSILON) * 100) / 100)
const mps = mph / 2.237
setMps(Math.round((mph + Number.EPSILON) * 100) / 100)
}
function ckph(kph, setMph, setMps) {
const mph = kph / 1.60934
setMph(Math.round((mph + Number.EPSILON) * 100) / 100)
const mps = mph / 2.237
setMps(Math.round((mps + Number.EPSILON) * 100) / 100)
}
function cmps(mps, setKph, setMph) {
const mph = mps * 2.237
setMph(mph)
const kph = mph * 1.60934
setKph(kph)
}
我想要的只是更改任何输入,所有其他输入都会自动反映新值。
PS:我减少了三个输入,所以例子会更小。但我有 19 个。
我该如何解决这个问题?
堆栈片段:
const { useState } = React;
const Example = () => {
const [mph, setMph] = useState(); // miles per hour
const [kph, setKph] = useState(); // kiliometers per hour
const [mps, setMps] = useState(); // miles per seconds
function cmph(mph, setKph, setMps) {
const kph = mph * 1.60934;
setKph(Math.round((kph + Number.EPSILON) * 100) / 100);
const mps = mph / 2.237;
setMps(Math.round((mph + Number.EPSILON) * 100) / 100);
}
function ckph(kph, setMph, setMps) {
const mph = kph / 1.60934;
setMph(Math.round((mph + Number.EPSILON) * 100) / 100);
const mps = mph / 2.237;
setMps(Math.round((mps + Number.EPSILON) * 100) / 100);
}
function cmps(mps, setKph, setMph) {
const mph = mps * 2.237;
setMph(mph);
const kph = mph * 1.60934;
setKph(kph);
}
return (
<div>
<input
value={mph}
size="5"
onChange={(e) => cmph(e.target.value, setKph, setMps)}
/>
<input
value={kph}
size="5"
onChange={(e) => ckph(e.target.value, setMph, setMps)}
/>
<input
value={mps}
size="5"
onChange={(e) => cmps(e.target.value, setKph, setMph)}
/>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
答:
有大量的 React-Ways 可以解决您的问题。
其中之一是使用带有每个输入/数据类型键的 Object。
然后,在输入中,使用属性查看哪个值发生了变化,将该值设置为新状态。对于状态对象中的所有其他键,找到正确的键并应用它。onChange
data-speed
convertFunction
我已经用一个简单的 / 函数替换了所有 / 函数,以保持演示的干净。cmps
ckph
convertFunction
const { useState } = React;
const Example = () => {
const [data, setData] = useState({
mph: 0,
kph: 0,
mps: 0
});
const convertFunction = (n) => Math.round(n * Math.random() * 16);
const onInput = (e) => {
const changedInputValue = +e.target.value;
const changedInputType = e.target.getAttribute('speed');
setData(p => {
const newData = { ...data };
for (var speed in p) {
if (speed === changedInputType) {
newData[speed] = changedInputValue;
} else {
// Choose correct convert function
newData[speed] = convertFunction(changedInputValue)
}
}
return newData;
});
}
return (
<div>
<input
value={data.mph}
size="5"
speed='mph'
onChange={onInput}
/>
<input
value={data.kph}
size="5"
speed='kph'
onChange={onInput}
/>
<input
value={data.mps}
size="5"
speed='mps'
onChange={onInput}
/>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
评论
问题在于您的输入是受控的,这意味着它们的值不会自动更新,除非您设置了用于设置其 .它最初起作用的原因是,如果不给 提供初始值,你就默认为 ,并使 React 认为输入不受控制。一旦更改值,输入就会从不受控制变为受控,并且停止工作。(如果你使用 React 库的开发版本进行开发,你会收到一个很大的警告。有关受控输入与非受控输入的更多信息,请参阅文档。value
useState
undefined
value={undefined}
相反:
- 使用初始值,以便它们不会默认为
useState
undefined
- 处理每个输入的事件时,更新控制它的状态成员
change
例如,对于:mph
const mphOnChange = ({ currentTarget: { value } }) => {
setMph(value); // <======================= This is what was missing
cmph(value, setKph, setMps);
};
工作示例(这些默认值可能需要调整):
const { useState } = React;
function cmph(mph, setKph, setMps) {
const kph = mph * 1.60934;
setKph(Math.round((kph + Number.EPSILON) * 100) / 100);
const mps = mph / 2.237;
setMps(Math.round((mph + Number.EPSILON) * 100) / 100);
}
function ckph(kph, setMph, setMps) {
const mph = kph / 1.60934;
setMph(Math.round((mph + Number.EPSILON) * 100) / 100);
const mps = mph / 2.237;
setMps(Math.round((mps + Number.EPSILON) * 100) / 100);
}
function cmps(mps, setKph, setMph) {
const mph = mps * 2.237;
setMph(mph);
const kph = mph * 1.60934;
setKph(kph);
}
const Example = () => {
const [mph, setMph] = useState(0); // miles per hour
const [kph, setKph] = useState(0); // kiliometers per hour
const [mps, setMps] = useState(0); // miles per seconds
const mphOnChange = ({ currentTarget: { value } }) => {
setMph(value);
// Recommend explicit conversion to number here
cmph(value, setKph, setMps);
};
const kphOnChange = ({ currentTarget: { value } }) => {
setKph(value);
// Recommend explicit conversion to number here
ckph(value, setMph, setMps);
};
const mpsOnChange = ({ currentTarget: { value } }) => {
setMps(value);
// Recommend explicit conversion to number here
cmps(value, setKph, setMph);
};
return (
<div>
<input value={mph} size="5" onChange={mphOnChange} />
<input value={kph} size="5" onChange={kphOnChange} />
<input value={mps} size="5" onChange={mpsOnChange} />
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
评论