'How can I pass an input value to a parent component in React?
I have a form component where I create the template of fields that can be initiated in another component, then in the parent component's template, I define fields properties. Problem is that my form submit button is in the parent component which means I have no access to input values from here.
This is Parent component:
function SignIn() {
//Here I will be doing API call and will need to use input values
};
function Login() {
let template = {
fields: [
{
title: data.email,
type: 'email',
name: data.email,
placeholder: data.inputPlaceholder,
icon: letter,
},
{
title: data.password,
type: 'password',
name: data.password,
placeholder: data.inputPlaceholder,
icon: lock,
}
]
}
return (
<Form template={template} />
<Button btnstyle={'mazhrBtn light-green'} onClick={SignIn}>
{data.signInButton}
</Button>
);
}
This is Form component:
function Form({ template, children, onSubmit, errors }) {
const [ value , setValue ] = useState('');
let [ formErrors, setFormErrors] = useState(false);
let { fields } = template;
const handleSubmit = (event) => {
event.preventDefault();
onSubmit({
text: value
});
if(errors) {
formErrors = true;
setFormErrors(formErrors);
} else {
formErrors = false;
setFormErrors(formErrors);
event.target.reset();
document.querySelector('.editable').innerHTML = "";
}
};
const renderFields = (fields) => {
return fields.map((field, index) => {
let { title, type, name, placeholder, icon, textArea, dropdown, dropdownTemplate } = field;
const onChange = (event) => {
let eName = event.target.name;
let eValue = event.target.value;
setValue({
...value,
[eName]: eValue
});
console.log(eName + ':' + eValue);
if(icon) {
if (event.target.value !== '') {
document.getElementById('icon' + index).classList.add('active');
} else {
document.getElementById('icon' + index).classList.remove('active');
}
}
};
return (
<div key={index} className="form-field">
<label htmlFor={name}>{title}</label>
<div className="input-wrapper">
{dropdown ?
<DropdownButton dropdownTemplate={dropdownTemplate} placeholder={placeholder} customClass='input'/>
:
textArea ?
<p className="m-0 editable"
contentEditable
type={type}
name = {name}
id={name}
placeholder={placeholder}
value={index.value}
onChange={onChange}
suppressContentEditableWarning={true}
onInput={
e => setValue(
{
...value,
[e.target.getAttribute("name")]: e.currentTarget.textContent
}
)
}
></p>
:
<input
type={type}
name={name}
id={name}
placeholder={placeholder}
value={index.value}
onChange={onChange}
/>
}
{icon ? <img id={'icon' + index} className="icon" src={icon} alt="icon"/> : ''}
</div>
</div>
)
})
}
return (
<>
<form className="form" onSubmit={handleSubmit}>
{ renderFields(fields) }
{children}
</form>
</>
)
}
Sorry in advance for a messy code, I'm learning React
Solution 1:[1]
In general, when you need the state in a parent component, the best thing to do is to lift the state up. See https://reactjs.org/docs/lifting-state-up.html
That means moving your state hooks to the parent component and passing them down as props to the child component
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Bernardo Ferreira Bastos Braga |
