I have a parent component and I have a child component;
Parent name is <Form>
Child name is <FormInput>
Im calling from form as formInput , Also I have a button into Form component the button has a attribute (disable), Also I have a local state into parrent component its name is isButtonDisable.
So I want to do this;
I check input from formInput is valid or not if both of them is not valid I should set local state isButtonDisable = true and then I should use from Form
So how can i handle both child component
<FormInput
onChange(this._onChange.bind(this))
onBlur(this._onBlur.bind(this))
/>
<FormInput
onChange(this._onChange.bind(this))
onBlur(this._onBlur.bind(this))
/>
Check this simple solution, you can change it a little for your needs.
Solution
Related
I am following a tutorial to create a multistep form with formik by creating a formik wrapper component . So far it works for normal field elements. But I have certain scenarios where I wish to use setFieldValue to set some values of custom component , the formik helpers are inaccessible to the child elements of the wrapper.
Can someone help me on how can I use formik helpers to set values of a child element of a wrapper.
Here is the example link which I am following.
This is what I am trying to achieve -
<FormikStepper
initialValues={{...values}}
onSubmit={someFunction}
onReset={() => {}}>
<FormikStep label='Step 1' validationSchema={Step1ValidationSchema}>
<label>Some Label</label>
<input
name='image'
type='file'
className=''
onChange={(e) => {setFieldValue("image", e.target.files[0]);}}
/>
<ErrorMessage name='image'/>
</FormikStep>
How can I be able to access it for setting the value of a child. I tried creating a context but I am confused on where to initialize the context .i.e As to where and how should I initialize the context for this particular scenario.
Better way is to extract input into separate component and then you can use setFieldValue inside that component:
const ImageInput = (props) = {
const [setFieldValue] = useFormikContext()
...
}
The reason why it works is that all your components wrapper by formik Form.
I have an input field in react, whose value is initially set by a props received by the component
<EditUserModal
show={this.state.showModal}
close={this.closeModal}
userId={this.state.rowId}
email={this.state.selectedMail}
/>
As you can see it received the value email, and inside the component I can see the valu changing properly
<div class="form-group emailgroup">
<label for="exampleFormControlInput1">Change Email Address</label>
<input
type="email"
class="form-control"
placeholder="name#example.com"
value={this.props.email}
onChange={this.handleChange}
/>
</div>
Problem is, that I add a handleChange event, to be able to modify that input, but it doesnt modify the email, I suppose that its because I should change the props in the parent component, but I dont understand how to do it. Currently my handleChange function looks like this.
handleChange = (evt) => {
this.setState({
email: evt.target.value
});
}
And this is the initial state fo the component
this.state = {
email : ""
};
Obviously since im not calling the state, but the props to asign the value of the field, it doesnt change. But ive tried....
this.state = {
email : props.email
};
And it lets me change it this way, but the problem is that it will render nothing initially in the input value.
Don't assign your props to state, instead call your function from parent and pass state value to child component.
you can refer this for better understanding of parent to child data flow.
How to change the state of a child component from its parent in React
You are passing the wrong value into the component. Current you have this:
email={this.state.selectedEmail}
But when you look at what you're setting in the parent component, it's not 'selectedEmail' but 'email'. Changing the property should fix it:
email={this.state.email}
Then the correct value should be worked on.
I am trying to make one login form in react .but I am getting this error
React does not recognize the handleChange prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase handlechange instead.
input value is also not setting input field when I type in input field it is not updating the state why ?
here is my code
https://codesandbox.io/s/quirky-clarke-qbkjw
<form noValidate>
<TextBox
label="Username"
name="username"
type="text"
helperText="Assistive text"
handleChange={handleChange}
handleMouseDownPassword={handleMouseDownPassword}
value={userId}
/>
<TextBox
label="Password"
name="password"
type="password"
helperText="Assistive text"
value={password}
showPassword={showPassword}
handleChange={handleChange}
handleClickShowPassword={handleClickShowPassword}
handleMouseDownPassword={handleMouseDownPassword}
/>
<div className="button-group">
<button>LOGIN</button>
</div>
</form>
In the TextBox component you're passing all the props from the parent via {...props}. Considering that TextField itself doesn't have handleChange property, I assume it passes it down to the underlying input DOM element, which doesn't recognise that prop.
What you can do is to extract the props used inside TextBox and collect the rest using the rest argument, so you don't end up passing unnecessary props down:
export default function TextBox({handleChange, handleClickShowPassword, handleMouseDownPassword, value, ...props}) {
Another option is to remove {...props} from the TextField component and explicitly pass all the necessary props.
Updated Sandbox
React doesn't like uppercase letters in the prop names. Instead of passing "handleChange", pass "handlechange". You will get a similar error for "handleMouseDownPassword".
Regarding the input issue, I don't think you've provided enough context. But you have to have a handleChange method to update the state each time the field is changed.
I changed the handleChange() function, you were only setting the VALUE state, you need to set the state userId when you write on the first input, and the password when you write to the second input
At b.js add props name={stateName} so the handleChange() can know which input is controlling
Check Demo for more:
https://codesandbox.io/s/gracious-heisenberg-z4q4z
(other answeres explained why you are getting that error in console ...props)
Problem statement :
Parent component having <form> tag and some <input> tags inside it, and child component also have some <input> tags, parent component has one <submit> and we are validating form fields on submit the form.
How to validate the child component <input> fields from parent component on submit the form ?
Requirement :
If a parent component has a form containing child components with input components in their template, then these input components should be validate on click if submit from the parent component.
Findings :
There are lot of posts in SO having same problem statement but did not find any suitable solution.All the below posts validate the whole form but my requirement is to validate each field in child component.
Angular 2 validation together with the child component
Allow template-driven form inputs across a component hierarchy to register with a single parent form
How to check the validity of the child component form within the parent component in Angular 4
We can achieve it using template driven technique as well. Find below the steps :
From parent component to child component we have to pass submit button event.
<button type="button" (click)="enterForm(parentForm)">Submit</button>
Here, parentForm is the form reference.
call child component method using #ViewChild decorator from parent to pass submit button event on click of submit.
#ViewChild('validateChildComponentForm') private ChildComponent: ChildComponent;
Pass the reference of child form using #ViewChild decorator into the child component.
#ViewChild('smartyStreetForm') form;
enterForm(parentForm) {
this.submitted = true;
this.ChildComponent.validateChildForm(this.submitted);
if(!parentForm.valid || !this.childFormValidCheck) {
return;
} else {
// success code comes here.
}
}
Now in child component method we will check that if parent form is submitted and child component form is valid then emit true otherwise false into the parent component. we will use #Output decorator to emit the isChildFormValid value into the parent component.
#Output() isChildFormValid: EventEmitter<any> = new EventEmitter<any>();
public validateChildForm(data: any) {
if (data === true) {
if(this.form.valid === true) {
this.isChildFormValid.emit(true);
} else {
this.isChildFormValid.emit(false);
}
}
}
Now in parent component we will get the isChildFormValid value.
private isChildFormValid(formValid: any) {
this.childFormValidCheck = formValid;
}
Pictorial representation :
how to retain component props after emitting back event.
Desc: i have a container it has multiple components (in a same view) in one of component has two fields and one button "continue". After entering some values into those fields , clicking on continue button its going to another component in this component we have two fields and two buttons one is back and continue when i click on back button its going to previous component but not retaining the props which entered on those . can you help me how to retain data.
The simplest solution for you is to have a parent component which holds all the data in its state. Parent container component passes the data to the children components you have as props, also it passes the callbacks to so a child can update the data. Given that you parent is always rendered and thus is never unmounted the data will be always there.
Something like this:
class Parent extends React.Component {
state = { name: 'John' }
render() {
return <div>
<Child name={this.state.name} onNameChange={e => this.setState({name: e.target.value})} />
</div>
}
}
class Child extends React.Component {
render() {
return <div>
<p>The name "{this.props.name}" is saved in the Parent</p>
<input type="text" value={this.props.name} onChange={this.props.onNameChange} />
</div>
}
}
A more complicated solution is to use something like Flux or Redux, but I believe it will be a bit too much for you now.