Reputation: 9909
I'd like my controlled input to initialize with no value in the box.
The input is a number, so I don't pass in an empty ''
.
Using defaultProps, I initialize the input with a null.
When typing into the input the console reports this message:
<MyInput>
is changing an uncontrolled input of type number to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa).
To prevent this normally I initialize with an empty string to prevent this "switching" from happening. But with a number (I don't want to show a 0, I want nothing to show) I am not sure how to do it.
static defaultProps = {
estimatedHours: null,
estimatedMinutes: null,
}
defalut values ^^
<input
type="number"
onChange={(e) => this.handleChange('Hours', e.target.value)}
onKeyDown={this.handleKeyDown}
onPaste={this.handlePaste}
value={estimatedHours}
placeholder={hoursText}
className="slds-input th-trailmix-textbox th-time-component__input"
/>
Upvotes: 35
Views: 32272
Reputation: 2537
I'd like my controlled input to initialize with no value in the box.
my problem is that I want a controlled number input with a null / undefined initial value.
I suggest defaulting the value props in the input element with an empty string like the following:
<input
type="number"
// ...
value={estimatedHours === undefined ? '' : estimatedHours}
/>
This will make the input empty and prevent the warning from React. It'll also conveniently work well with the required
prop too so the user must enter an input.
In TypeScript 3.7+, it can be shorted to the following using the nullish coalescing operator:
<input
type="number"
// ...
value={estimatedHours ?? ''}
/>
Upvotes: 3
Reputation: 377
Simpler approach is to have a fallback value be an empty string.
Works for type=number
as well.
<input type="number" value={estimatedHours || ''} />
Upvotes: 16
Reputation: 2674
The easiest way to get the behaviour you are looking for is to define the prop type for this field to a string
. This will allow ''
to be used as a default prop. On form submission, you will need to make sure that the value of this field is parsed to a number.
type FormProps = {
estimatedHours: string;
estimatedMinutes: string;
}
FormProps.defaultProps = {
estimatedHours: '',
estimatedMinutes: '',
}
Upvotes: -2
Reputation: 797
You can set value Undefined,
Also add a check for input type if required
class Input extends React.Component {
constructor(props) {
super(props);
this.state = {value: undefined};
this.handleChange = this.handleChange.bind(this);
}
handleChange = (event) => {
const isnum = /^\d+$/.test(event.target.value);
if (isnum) {
return this.setState({
value: Number(event.target.value),
});
}
};
render() {
return (
<input
type="number"
onChange={this.handleChange}
value={String(this.state.value)}
placeholder={"Please enter number"}
/>
);
}
}
and convert String to Number and vice versa
This won't throw you an error for uncontrolled input
Upvotes: 3
Reputation: 175
Uncontrolled inputs are simply inputs where you aren't tying value
to JavaScript. So if you are rendering:
<input value={any} />
That is a controlled input.
If you want to render an uncontrolled input with an empty value you could simply write
<input type="number" /> or <input type="number" placeholder="" />
or <input type="number" placeholder="please enter a number..." />
Next, if you want to pull the value use a ref.
state = {
query: ''
}
handleSubmit = (e) => {
e.preventDefault()
this.setState({ query: this.search.value })
}
render() {
return (
<form>
<input
type="number"
ref={input => this.search = input}
placeholder=""
/>
<button type="submit" onClick={this.handleSubmit}>Submit</button>
</form>
)
}
Additionally, you can still perform logic on the return value if you need to. ie:
handleSubmit = (e) => {
e.preventDefault()
this.setState({ query: this.search.value.toExponential(2) })
// square whatever the user inputs and store in this.state.query
}
Upvotes: -1