英文:
How do I limit a React input field to a parent min and max props?
问题
以下是您提供的代码的翻译:
我在React中还很新,我试图将输入限制为最小值-10和最大值10。我已经使输入能够接受输入,并尝试使用useState和useEffect钩子来尝试更改和设置输入中的值。无论输入中包含什么内容,当您点击离开它时,它应该被限制为-10或10。我知道有onBlur来触发一个函数或状态,但我不知道从哪里开始。任何帮助将不胜感激。
// 供参考,此组件由其父组件呈现,如下所示:
//
// const ParentForm = () => {
// const [value, setValue] = useState(0)
// return (
// <NumberSelector
// min={-10}
// max={10}
// value={value}
// onChange={setValue}
// css={{ background: theme.white }}
// />
// )
// }
const NumberSelector = ({
min = -10,
max = 10,
value,
onChange: setValue,
className,
}) => {
const [tempValue, tempSetValue] = useState(0)
useEffect(() => {
}, [tempValue])
return (
<div
css={{
display: "flex",
border: `3px solid ${theme.richBlack}`,
borderRadius: 5,
}}
className={className}
>
<StepButton
aria-label="减少一个"
tabIndex="-1"
onClick={() => {
setValue((prev) => prev - 1)
}}
>
<svg width="16" height="16" viewBox="0 0 16 16">
<rect x="0" y="6.5" width="16" height="3" fill={theme.richBlack} />
</svg>
</StepButton>
<input
type="text"
maxLength={Math.max(min.toString().length, max.toString().length + 1)}
css={inputStyles}
value={tempValue}
onChange={(e) => tempSetValue(e.target.value)}
/>
<StepButton
aria-label="增加一个"
tabIndex="-1"
onClick={() => {
setValue((prev) => prev + 1)
}}
>
<svg width="16" height="16" viewBox="0 0 16 16">
<rect x="0" y="6.5" width="16" height="3" fill={theme.richBlack} />
<rect x="6.5" y="0" width="3" height="16" fill={theme.richBlack} />
</svg>
</StepButton>
</div>
)
}
export default NumberSelector
NumberSelector.propTypes = {
min: PropTypes.number,
max: PropTypes.number,
value: PropTypes.number.isRequired,
onChange: PropTypes.func.isRequired,
className: PropTypes.string,
}
请注意,这是您提供的代码的中文翻译,不包括代码部分。如果您需要任何其他帮助,请告诉我。
英文:
I am quite new to react here. I am trying to constrain my input to min -10 and max 10 input value. I have it so the input can accept input and I am trying to use hooks useState and useEffect to try to change and set the value in the input. No matter what is in the input when you click off of it it should be constrained to -10 or 10. I know there is onBlur to trigger a function or state for that, but I don't know where to go from there. Any help would be greatly appricated.
// For reference, this component is rendered
// by its parent like this:
//
// const ParentForm = () => {
// const [value, setValue] = useState(0)
// return (
// <NumberSelector
// min={-10}
// max={10}
// value={value}
// onChange={setValue}
// css={{ background: theme.white }}
// />
// )
// }
const NumberSelector = ({
min = -10,
max = 10,
value,
onChange: setValue,
className,
}) => {
const [tempValue, tempSetValue] = useState(0)
useEffect(() => {
}, [tempValue])
return (
<div
css={{
display: "flex",
border: `3px solid ${theme.richBlack}`,
borderRadius: 5,
}}
className={className}
>
<StepButton
aria-label="Reduce by one"
tabIndex="-1"
onClick={() => {
setValue((prev) => prev - 1)
}}
>
<svg width="16" height="16" viewBox="0 0 16 16">
<rect x="0" y="6.5" width="16" height="3" fill={theme.richBlack} />
</svg>
</StepButton>
<input
type="text"
maxLength={Math.max(min.toString().length, max.toString().length + 1)}
css={inputStyles}
value={tempValue}
onChange={(e) => tempSetValue(e.target.value)}
/>
<StepButton
aria-label="Increase by one"
tabIndex="-1"
onClick={() => {
setValue((prev) => prev + 1)
}}
>
<svg width="16" height="16" viewBox="0 0 16 16">
<rect x="0" y="6.5" width="16" height="3" fill={theme.richBlack} />
<rect x="6.5" y="0" width="3" height="16" fill={theme.richBlack} />
</svg>
</StepButton>
</div>
)
}
export default NumberSelector
NumberSelector.propTypes = {
min: PropTypes.number,
max: PropTypes.number,
value: PropTypes.number.isRequired,
onChange: PropTypes.func.isRequired,
className: PropTypes.string,
}
答案1
得分: 1
Sure, here is the translated content:
由于 NumberSelector
组件完全由父组件控制,因此不应该有本地状态来存储值。useEffect
也是不必要的。
然后,您可以附加一个 onBlur
处理程序来夹紧值。
<input
type="text"
maxLength={Math.max(min.toString().length, max.toString().length + 1)}
value={value}
onChange={e => setValue(e.target.value)}
onBlur={e => {
if (value && !isNaN(value))
setValue(Math.min(max, Math.max(min, value)));
}}
/>
对于增加和减少按钮,您需要检查在增加后值不会超出有效范围。
<StepButton
aria-label="减少一个"
tabIndex="-1"
onClick={() => setValue(Math.max(min, value - 1))}>
// ...
<StepButton
aria-label="增加一个"
tabIndex="-1"
onClick={() => setValue(Math.min(max, value + 1))}>
Note: I've left the code parts untranslated as per your request.
英文:
Since the NumberSelector
component is completely controlled from the parent, you should not have local state to store the value. The useEffect
is also unnecessary.
You can then attach an onBlur
handler to clamp the value.
<input
type="text"
maxLength={Math.max(min.toString().length, max.toString().length + 1)}
value={value}
onChange={e => setValue(e.target.value)}
onBlur={e => {
if (value && !isNaN(value))
setValue(Math.min(max, Math.max(min, value)));
}}
/>
For the increment and decrement buttons, you need to check that the value will not exceed the valid range after incrementing.
<StepButton
aria-label="Reduce by one"
tabIndex="-1"
onClick={() => setValue(Math.max(min, value - 1))}>
// ...
<StepButton
aria-label="Increase by one"
tabIndex="-1"
onClick={() => setValue(Math.min(max, value + 1))}>
答案2
得分: 0
这与React无关。
据我理解,您正在寻找数值。然后:
<input
type="number"
min={min}
max={max}
css={inputStyles}
value={tempValue}
onChange={(e) => tempSetValue(e.target.value)}
/>
有关更多信息,请参阅输入类型。
英文:
This has nothing to do with React.
As I understand you are looking for the numeric value. Then:
<input
type="number"
min={min}
max={max}
css={inputStyles}
value={tempValue}
onChange={(e) => tempSetValue(e.target.value)}
/>
For more information Input type
答案3
得分: 0
Usually it isn't recommended to use useEffect
for any side-modifications.
You can try having some custom handling in the onChange
:
const onTempChange = (e) => {
// default to 1 if no input is entered
let tempFloat = parseFloat(e.target.value || '1');
// default to 1 if input is invalid
if (isNaN(tempFloat)) {
tempFloat = 1;
} else {
tempFloat = Math.min(max, Math.max(min, tempFloat));
}
// usually you name the setter something like setTempValue
tempSetValue(tempFloat);
};
return (
// ...
<input ... onChange={onTempChange} />
);
Obviously there's room for improvement with the code, but that's the gist of one way you can control the input value given to the setter.
If you want this to only happen after the user leaves the input, then you'll just need to listen to another event (onFocusOut iirc?).
Hope this helped.
英文:
Usually it isn't recommended to use useEffect
for any side-modifications.
You can try having some custom handling in the onChange
const onTempChange = (e) => {
// default to 1 if no input is entered
let tempFloat = parseFloat(e.target.value || '1');
// default to 1 if input is invalid
if (isNan(tempFloat) {
tempFloat = 1;
} else {
tempFloat = Math.min(max, Math.max(min, tempFloat));
}
// usually you name the setter something like setTempValue
tempSetValue(tempFloat);
};
return (
// ...
<input ... onChange={onTempChange} />
);
Obviously there's room for improvement with the code, but that's the gist of one way you can control the input value given to the setter.
If you want this to only happen after the user leaves the input, then you'll just need to listen to another event (onFocusOut iirc?).
Hope this helped.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论