I have created form elements that I can configure in different ways to create forms.
Here's an example of that:
<form>
<Label htmlFor="name" name="Enter name:" />
<InputWrapper>
<Input id="name" name="name" />
</InputWrapper>
<CharacterLimit />
</form>
What I would like to do is set a maxLength
& required
prop
on my Input
component and it will cause my Label
component to then have a red asterisk( * ) and my CharacterLimit
component to display the maxLength
set on my Input
component.
Here's what my Label
component looks like:
interface ILabel {
htmlFor: string;
name: string;
required?: boolean;
}
export const Label: React.FC<ILabel> = ({ htmlFor, name, required }) => {
return (
<StyledLabel htmlFor={htmlFor}>
{name} {required && <StyledRequired>*</StyledRequired>}
</StyledLabel>
);
};
const StyledLabel = styled.label`
font-weight: 600;
`;
const StyledRequired = styled.span`
color: red;
`;
And here's what my CharacterLimit components look like:
interface ICharacterLimit {
maxLength?: number;
}
export const CharacterLimit: React.FC<ICharacterLimit> = ({ maxLength }) => {
return (
<>
{maxLength && (
<StyledCharacterLimit>0 / {maxLength} Characters</StyledCharacterLimit>
)}
</>
);
};
Now you're probably wondering why I don't just put the
Label
&CharacterLimit
components inside of myInput
component and conditionally render them that way.
Well, I have another component as you can see called InputWrapper
, this is used to style the "container" of the input
, the reason I wanted to make this styling separate, is so then I could put an input
and a button
inside of the container for example.
Here's an illustration to example better what I mean:
How can I get the props passed from my Input
component to the Label
and CharacterLimit
components? Or is there another approach to achieve them the same layouts in my illustration?
I have put together a demo on CodeSandBox
This is not necessarily an answer, but too long for comment
Something like this:
const FormModel = () => {
const [formModel, setFormModel] = useState();
const updateFormModel = name => value => setFormModel({
...formModel,
{ [name]: value }
});
return (
<form>
<InputWrapper onChange={updateForm("something")} isValid={validate(formModel)} />
<form>
);
};
const InputWrapper = ({ onChange, isValid }) => {
// returns appropriate stuff, including
// <input onChange={e => onChange(e.currentTarget.value)} />
// styled based on isValid prop. May also want to debounce
// input, but whateves.
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.