Nicoara
Nicoara

Reputation: 390

How to validate a child's component data from the parent without useEffect on each input

I have a reactjs component called payment that has and addressForm child componenet.

Now in my payment I have a next button that user needs to press to move to the next step but before moving the parent needs to validate the addressFrom's data.

Payment (PARENT)

<div ref={sliderRef} className='slider'>
                <AddressForm 
                  callback={(data) => registerAddress(data)}
                  setCanGoNext={val => setCanGoNext(val)}/>
                <Paymentform/>
                <InformationalForm/>
              </div>

AddressForm (CHILD)

<div className="input-container-parent">
        <div className="input-container-left">
          <Input label="Country" value={country} setValue={e => setCountry(e)}/>
          <Input label="County" value={county} setValue={e => setCounty(e)}/>
          <Input label="City" value={city} setValue={e => setCity(e)}/>
          <Input label="Street name and number" value={streetAndNumber} setValue={e => setStreetAndNumber(e)}/>
          <Input label="Zipcode" value={zipcode} setValue={e => setZipcode(e)}/>
        </div>
        <div className="input-container-right">
          <Input label="Person of contact" value={person} setValue={e => setPerson(e)}/>
          <Input label="Phone number with contry prefix" value={phone} setValue={e => setPhone(e)}/>
          <Input label="Email address" value={email} setValue={e => setEmail(e)}/>
          <Input label="Adittional info" value={additionalInfo} setValue={e => setAdditionalInfo(e)}/>
          <Input label="Note" value={note} setValue={e => setNote(e)}/>
        </div>
        <div>

Now my question is: can I validate somehow this data from the parent ONLY on click of the button 'next'. So I don't have to useEffect in child with all the child's properties to check if the form is valid or not

Upvotes: 0

Views: 1593

Answers (1)

Pallamolla Sai
Pallamolla Sai

Reputation: 2493

I have created sample email validation below. We will call child's method(which will be validating the email) from the parent upon clicking the next button. I am using react hooks in the below example.

Parent Component

import { Child } from "./Child";
import { useRef } from "react";

export default function Parent() {
  const childRef = useRef();

  const validateChildProperties = () => {
     console.log(childRef.current.validateEmail()); // consoles whether the email is valid or not
  };
  return (
    <>
      <Child ref={childRef} />
      <button onClick={() => validateChildProperties()}>Next</button>
    </>
  );
}

Child Component

import React, { useState, forwardRef, useImperativeHandle } from "react";

export const Child = forwardRef((props, ref) => {
  const [email, setEmail] = useState("");

  useImperativeHandle(ref, () => ({
     validateEmail() {
       return isValidData();
     }
  }));

  const isValidData = () => {
      const regex = /^((?!\.)[\w\-_.]*[^.])(@\w+)(\.\w+(\.\w+)?[^.\W])$/;
      return regex.test(email);
  };

  return (
    <>
      <input
         type="text"
         onChange={(e) => setEmail(e.target.value)}
         placeholder="enter your email"
      />
      <span>Email is {email}</span>
    </>
  );
});

Please find the below link which is having examples of both functional component and class component.

https://codesandbox.io/s/stackoverflow-6u05e7?file=/src/Validation/Parent.js

Upvotes: 5

Related Questions