I’m trying to create components a (parent, child and input) and pass variables from the parent component to child and input components, allow for the variables to change within the child components and access the mutated variable in the parent component. With the below code, the text doesn’t update when typing in the input field, and my setValue
function isn’t called in the parent component. Also, as you can see in my code below, the function setValue
is there to handle all of the possible variable changes, but I’m not sure how to implement that. Any help would be greatly appreciated. Thank you.
const { useState } = React;
function CreateAccount() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const setValue = (newValue, valueType) => {
if (valueType === 'email') setEmail(newValue);
else if (valueType === 'password') setPassword(newValue);
else setConfirmPassword(newValue);
};
return (
<div>
<Form
email={email}
password={password}
confirmPassword={confirmPassword}
viewType='createClientAccount'
onChangeState={setValue}
/>
<hr/>
<div>Email is:{email}</div>
</div>
);
}
function Form({ email, password, confirmPassword, viewType, onChangeState }) {
if (viewType === 'createClientAccount') {
return (
<div className='box-shadow'>
<h2>Create Client Account</h2>
<TextInputField
label={'Email'}
value={email}
onChangeState={onChangeState}
/>
</div>
);
}
}
function TextInputField({ label, value, onChangeState }) {
function onChange() {
onChangeState(value);
}
return (
<div className='inputFieldWrapper'>
<p>{label}</p>
<input name='email' value={value} onChange={onChange} />
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<CreateAccount />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
2
Answers
Your function
onChange()
in theTextInputField
is not passing the change value toonChangeState()
. It is only passing the value of thevalue
prop, which is the original value being passed in from the parent.Additionally, the "onChange handler" for the
<input> onChange prop
is passed an Event object, from which you would extract the newly typed value.So try changing it to:
There are several issues with the code you provided:
your function
onChange()
in theTextInputField
is not passing the change value toonChangeState()
. It is only passing the value of thevalue
prop, which is the original value being passed in from the parent.the "onChange handler" for the
<input> onChange prop
is passed an Event object, from which you would extract the newly typed value.the
setValue()
function you are passing down requires 2 parameters (type and value).the
label
props (which appears to be a rename oftype
expected bysetValue()
was given the value of"Email"
but the code insetValue()
was checking for the value of"email"
(lower-case).This snippet I think shows a bit of what you were trying to accomplish?