I have a loading component that creates a skeleton until the content renders via @trainline/react-skeletor
. In this case I am creating a skeleton for a form.
First off, I have a CodeSandbox for those who want to see what is occurring, and all the Components used for a better idea of a solution.
I am also using a Function Based Component, and wish to keep it that way, unless this is impossible to do via a Function Based Component I do not want to use a Class Based Component to fix this issue.
I have a component ProfileForm
that contains, at the moment, an h3
and a form
The form is as follows
const form = (
<>
<FormControl key={"profileForm"} submit={profileFormSubmit} form={profileFormData} validation={profileFormValidation}>
<InputControl autoComplete="off" type="text" name="emailAddress" placeholder="Email address" label="Email Address">
<ErrorMsg map="required" msg="Email is required"></ErrorMsg>
</InputControl>
</FormControl>
</>
)
FormControl
Component returns a <form>
element
InputControl
Component returns a <label>
and <input>
element
ErrorMsg
Component returns a <div>
Will render as the following.
<form class="Form " novalidate="">
<div class="InputControl">
<div>
<label for="emailAddress">Email Address</label>
<input type="text" placeholder="Email address" name="emailAddress" id="emailAddress" autocomplete="off" value=""></div>
<div class="InputControl--Errors">
</div>
</div>
</form>
I have created a dummy http request where I update a state object with a title and the form above.
const [content, setContent] = useState();
const ttl = 500;
/*simulate http request*/
useEffect(() => {
const timeout = setTimeout(() => {
setContent({ title: "My Personal Details", form });
}, ttl);
return () => {
clearTimeout(timeout);
};
}, []);
In my return, I pass down the content
state object as a prop (The commented out code works but will not create the skeleton loading element that is required in my project
return (
<div className="ProfileForm">
<h2 style={{ color: "red" }}>Not working: Passing Form Down to Child</h2>
<ProfileFormContainer content={content} />
{/* <h2 style={{ color: 'green' }}>Working: Render Directly in return</h2>
{form}*/}
</div>
);
ProfileFormContainer
creates the skeleton element and then passes the props down into another Component and gets returned in the code snippet below.
const Wrapper = createSkeletonElement('div', 'Loader Loader--InlineBlock ProfileForm--loading');
const H3 = createSkeletonElement('h3', 'Loader Loader--InlineBlock');
const DIV = createSkeletonElement('div', 'Loader Loader--Block ');
const ProfileFormLoader = (props) => {
return (
<Wrapper className="ProfileForm">
<H3 className="ProfileForm-title">{ props.title }</H3>
<DIV>
{props.form}
</DIV>
</Wrapper>
);
}
export default ProfileFormLoader;
This renders as expected, however, when I try to type in the input, It does not update the value of the input. My question is, how do I update the value of an input, on input when the input is passed down as a prop to a child component as I have done?
Any help would be greatly appreciated