I have a component I built using React Hooks that features a conditional function for email validation. As it stands now whenever a user leaves the input field, if the field is blank or the format is incorrect an error message will display underneath the input for the type of error respectively. I'm trying to also dynamically change the border color of the input to red to further signal that the field needs attention. I'm pretty new to hooks so I've been tooling around but can't quite figure out how to make this work as is
import React from "react";
import styled from "styled-components";
import { Col, Row, Input, Checkbox } from "antd";
function validateEmail(value) {
const errors = {};
if (value === "") {
errors.email = "Email address is required";
} else if (!/\S+@\S+\.\S+/.test(value)) {
errors.email = "Email address is invalid";
}
return errors;
}
const CustomerDetails = ({ customer }) => {
const { contact = {} } = customer || {};
const [disableInput, setDisableInput] = React.useState(false);
const [errors, setErrors] = React.useState({});
const [inputValue, setInputValue] = React.useState(contact.email);
function onBlur(e) {
setErrors(validateEmail(e.target.value));
}
function clearInput() {
setInputValue(" ");
}
function handleInputChange(event) {
setInputValue(event.target.value);
}
function CheckboxClick() {
if (!disableInput) {
clearInput();
}
setDisableInput(prevValue => !prevValue);
}
return (
<Container>
<Row>
<Col span={8}>
<StyledInput
value={inputValue}
onChange={handleInputChange}
disabled={disableInput}
onBlur={onBlur}
/>
{errors.email && <ErrorDiv>{errors.email}</ErrorDiv>}
</Col>
<Col span={8}>
<Checkbox value={disableInput} onChange={CheckboxClick} /> EMAIL OPT
OUT
</Col>
</Row>
</Container>
);
};
const Container = styled.div`
text-align: left;
`;
const StyledInput = styled(Input)`
max-width: 100%;
background: white;
&&& {
border: 2px solid black;
border-radius: 0px;
height: 35px;
}
`;
const ErrorDiv = styled.div`
color: #d11314;
`;
export default CustomerDetails;
The question is not about the hooks, but how to better apply the style conditionally. As Jonas Wilms already mentioned, the inline styles should fit in this particular case. Otherwise, if you want to have more flexible "styled component" consider using props
inside the component declaration, in your case it can be:
const StyledInput = styled(({ isError, ...rest }) => <Input {...rest} />)`
max-width: 100%;
background: white;
&&& {
border: 2px solid ${props => props.isError ? 'red' : 'black'};
border-radius: 0px;
height: 35px;
}
`;
so when you render it - just pass this prop directly as:
<StyledInput
...
isError={!!errors.email}
/>