Here, I attempted to create a custom component that can receive data through props and function as a basic form input.
However, I encountered an issue where errors are not being displayed. Can someone please explain what mistake I might have made in my implementation?
If anyone has the knowledge, I would greatly appreciate your assistance in resolving this issue.
trying to build an reuseable component but now working why??
/* eslint-disable react/prop-types */
const Input = (props) => {
const {formik, icon, title,type,otherState,btn1,btn2, name} = props
Input.defaultProps = {
type: "text",
otherState: null,
btn1: null,
btn2: null,
name: title.toLowerCase()
}
if (otherState) {
var {state, setState} = otherState
}
if (btn1) {
var {icon1, text1, action1} = btn1
}
if (btn2) {
var {icon2, text2, action2} = btn2
}
return (
<div className="mb-2">
<span className="flex">
<img className="w-6 h-6 mr-2" src={icon} alt={title} />
<label
htmlFor={name}
className="block text-sm font-semibold text-textPrimary dark:text-dark_textPrimary"
>
{title}
</label>
</span>
<span className="flex w-full">
{console.log(formik.touched.name)}
<input
type={type}
name={name}
value={formik.values.name}
title={`${formik.touched.name && formik.values.name == "" ? `${title} is required` : ""}`}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
placeholder={
formik.touched.name && formik.errors.name
? `${title} is required`
: `${title}`
}
className={`block w-full px-4 py-2 mt-2 text-textPrimary dark:text-dark_textPrimary bg-background dark:bg-dark_background border-2 rounded-md focus:ring-secondary ${
formik.touched.name && formik.errors.name
? " border-error_red placeholder-error_red"
: "border-cardBorder dark:border-dark_cardBorder"
}`}
/>
{
btn1 || btn2 ? (
<img
className="w-6 h-7 cursor-pointer mt-3 transition duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-110"
onClick={() => action1()}
src={state ? icon1 : icon2}
title={!state ? text1 : text2}
/>) : null
}
</span>
{
formik.touched.name && formik.errors.name && formik.values.name != "" ? (
<h3 className="text-xs text-error_red">{formik.errors.name}</h3>
) : null
}
</div>
)
}
export default Input
Here is a Input component,
That first components for email and second for password
<Input
formik={formik}
icon={emailIcon}
title="Email"
name="email"
type="email"
/>
<Input
formik={formik}
icon={passwordIcon}
name="password"
title="Password"
type={showPassword ? "password" : "text"}
otherState={{'state':showPassword, 'setState':setShowPassword}}
btn1={{'icon1':eyeOpenIcon, 'text1':"Hide Password", 'action1':() => setShowPassword(!showPassword)}}
btn2={{'icon2':eyeCloseIcon, 'text2':"Show Password", 'action2':() => setShowPassword(!showPassword)}}
/>
2
Answers
To access the value or the error related to a given input, you should use its name. Since inside your
Input
component, you are getting the name as part of aname
prop, you would do like this:Formik has tons of different examples you can use on their GitHub and documentation.
Rather than spin up your own, you could potentially build off one of their examples so to speak.
For example, there is this example which gives immediate feedback for validation on the fields. Take a look at this codesandbox and code below:
index.js