I have a problem in handling input's value changing
so here is my code in react,onChange works but when i clear the default value it doesn't log anything until i do another change.
<Form.Control
type="text"
placeholder="name"
defaultValue={this.state.name}
onChange={e=>console.log(e.target.value)}
/>
I wrote console.log just for test.
Value is not changing because in reactjs component rerenders once state chages and using console.log on onChange does not update any change in state. so you have to update the state on onChange event,
Try following, I am assuming it is class component as you have used this.state.name
<Form.Control
type="text"
name="name"
placeholder="name"
defaultValue={this.state.name || ""}
value={this.state.name}
onChange={e=>this.setState({name:e.target.value})}
/>
Use value instead of default value:
<Form.Control
type="text"
placeholder="name"
value={this.state.name || ""}
onChange={e=>console.log(e.target.value)}
/>
Try using an empty value instead of giving it null
<Form.Control
type="text"
placeholder="name"
value={this.state.name || ""}
onChange={e=>console.log(e.target.value)}
/>
Updated
Try with uncontrolled input:
<Form.Control
type="text"
placeholder="name"
onChange={(e) => console.log(e.target.value)}
/>
Related
const AddItem = () => {
const [user] = useAuthState(auth);
const navigate = useNavigate();
const handleAddCar = (e) => {
e.preventDefault();
const carObj = {
name: e.target.name.value,
supplier: e.target.supplier.value,
email: user.email,
price: parseInt(e.target.price.value),
quantity: parseInt(e.target.quantity.value),
description: e.target.description.value,
img: e.target.image.value,
sold: parseInt(e.target.sold.value),
};
axios
.post("http://localhost:5000/car", carObj)
.then((response) => {
toast("Successfully Added");
});
e.target.reset();
};
return (
<div>
<Container>
<Row>
<div className="col-md-6 mx-auto">
<h2 className="my-5">Add A Car</h2>
<Form onSubmit={handleAddCar}>
<Form.Group className="mb-3" controlId="formBasicModel">
<Form.Label>Model</Form.Label>
<Form.Control type="text" name="name" required />
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicSupplier">
<Form.Label>Supplier</Form.Label>
<Form.Control type="text" name="supplier" required />
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email</Form.Label>
<Form.Control
type="email"
value={user.email}
readOnly
disabled
/>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPrice">
<Form.Label>Price</Form.Label>
<Form.Control type="number" name="price" required />
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicQuantity">
<Form.Label>Quantity</Form.Label>
<Form.Control type="number" name="quantity" required />
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicDescription">
<Form.Label>Description</Form.Label>
<br />
<textarea
className="w-100"
name="description"
required
></textarea>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicImage">
<Form.Label>Image</Form.Label>
<Form.Control type="text" name="image" required />
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicImage">
<Form.Label>Sold</Form.Label>
<Form.Control type="number" name="sold" required />
</Form.Group>
<Button variant="primary" type="submit" className="w-100 fw-bold">
Add Car
</Button>
</Form>
</div>
</Row>
</Container>
</div>
);
};
I am trying to add an item in mongodb database by a form where I set some default value and required all input field. It is working properly but getting a warning on console "A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen."
Your problem is here:
<Form.Control
type="email"
value={user.email}
readOnly
disabled
/>
You can see you're setting the value of this component to user.email, making it a controlled input (where the value is passed in, and controlled from a parent component usually via a state).
an uncontrolled component is - basically - one where the value is not passed in, and the component itself deals with the value.
I'd guess that your user object (or the email parameter at least) is undefined to begin with, and then populates via an API call of some kind.
you either need to always have user.email parameter available when this input is rendered (eg. wrap the input in a check so it only renders when user.email !== undefined or add in a placeholder email param when the user object is first initialised), or less ideally supply a value for when the value is undefined. (eg. value={user.email ?? '-'} )
//form.js
const form=({seg,onSubmit,onChange})=>{
<form id="input_form" onSubmit={onSubmit}>
{seg.map(item=>
<>
<input type="number" onChange={onChange} name={item}
type="number" required className="form-control control" id={item+1} />
</>
)}
</form>}
// app.js
state={array:[0.0,1.0], seg=3}
onSubmit=()=>{
}
onChange=()=>{
// should update the array(as this.state.array=[0.0, inputa,inputb,inputc..., 1.0])}
how do i update the array? what should be the onChange, onSubmit func?
(this.state.seg is variable).
You can use this.setState({ seg : newValue});
You can set the seg state property value like this
onChange=(event)=>{
this.setState({seg: event.target.value});
}
I suppose yo need to update the array with current seg value. If you want to do it using onSubmit, you have to use a button with type of submit. Then the button calls the onSubmit function. Try this.
<form id="input_form" onSubmit={onSubmit}>
{seg.map(item =>
<>
<input type="number" onChange={onChange} name={item} type="number" required className="form-control control" id={item + 1} />
<button type="submit">Submit</button>
</>
)}
</form>
onSubmit=()=>{
this.setState({
array: [...this.state.array, seg]
})
}
To set the autocomplete off for a simple input it must be done like this: <input type="text" autocomplete="off">
In this case, there is a Formik Field and the input looks like this:
<Field
className="my-class"
name="myValues"
as={Input}
placeholder="Write something"
/>
and it seems that adding autocomplte="off" doesn't work in this case:
<Field
className="my-class"
name="myValues"
as={Input}
placeholder="Write something"
autocomplete="off"
/>
Any ideas?
Solution: camelCase.
Instead of autocomplete='off', use autoComplete='off'.
I am not sure where you are doing wrong. You can simply do this:
<label>
<Field name="picked" value="One" autocomplete="off" />
One
</label>
According to doc if you don't pass anything it will treat as a input
Here is the demo:https://codesandbox.io/s/happy-khayyam-9mdll?file=/index.js
<Field
name="password"
type="password"
component={() =>
<input
className="form-control"
type="password"
autoComplete="new-password"
/>
}
/>
In Formik, I try to use {...formik.getFieldProps('email')} on my input field
instead of using value, onChange, and onBlur. But it's not working.
This works :
<input id="email" name="email" type="text" value={formik.values.email} onChange={formik.handleChange} onBlur={formik.handleBlur} />
But this doesn't :
<input id="email" type="text" {...formik.getFieldProps("email")} />
Code is here : https://codesandbox.io/s/formik-pb-with-getfieldprops-83tze?fontsize=14
Any ideas ?
Thanks !
As MiDas said, what you are doing should work if you are on latest version.
I'll mention an even more concise alternative: the Field component.
Field component handles the field property propagation for you.
Simple example:
<Field name="email" type="text" />
Notice that you don't need to do {...formik.getFieldProps("email")}, or any other "boilerplate".
Related to Field is useField, which can be used to make custom form components just as easy to use - no "boilerplate" needed.
A custom component:
function TextInputWithLabel({ label, ...props }) {
// useField() returns [formik.getFieldProps(), formik.getFieldMeta()]
// which we can spread on <input> and also replace ErrorMessage entirely.
const [field, meta] = useField(props);
return (
<>
<label
htmlFor={props.id || props.name}
css={{ backgroundColor: props.backgroundColor }}
>
{label}
</label>
<input className="text-input" {...field} type="text" {...props} />
{meta.touched && meta.error ? (
<div className="error">{meta.error}</div>
) : null}
</>
);
}
Usage:
<TextInputWithLabel name="input1" label="Random comment" />
As seen in code from codesandbox.
redux-form input type is returning string , it should have returned number
Replicated problem
so i used parse to convert it to number
<Field
name="age"
parse={value => Number(value)}
component="input"
type="number"
placeholder="Age"
/>
Note : In redux form it Shows string
But the problem is it does let us remove last DIGIT ZERO
It happens because Number('') return 0. So Instead of setting the parse attribute to Field, you could just parse the value wherever you need
<form onSubmit={handleSubmit}>
<div>
{age ? <div>{typeof Number(age)} {`${age}`}</div>: null}
</div>
<div>
<label>Age</label>
<div>
<Field
name="age"
component="input"
type="number"
placeholder="Age"
/>
</div>
</div>
</form>
CodeSandbox