Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

316
Views
React: How to get a group value of components?

I have a input component that does validation. In a reduced form it looks like this:

const InputField = ({validation, name}) => {
  const [value, setValue] = useState("");
  const [error, setError] = useState(false);

  const handleChange = (e) => {
    let errors = 0;

    if (validation.includes("required") && val === "") {
      errors++;
    }
    
    if (errors > 0) {
      setError(true);
    } else {
      setError(false);
    }
    setValue(e.target.value)
  }

  return (
    <input
      type="text"
      value={value}
      onChange={handleChange}
      name={name}
    />
  );
};

If I am using this component multiple times in a parent like

const Parnet = () => {

  // ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ help required here
  const groupedErrorValueBool = true;

  return (
    <>
      <InputField name="Name" validation="required" />
      <InputField name="Email" validation="required" />
      <InputField name="Birthday" validation="required" />
      <button disabled={groupedErrorValueBool}>Submit</button>
    </>
  );

How can I get a grouped value of errors? Like: I want to disable a submit button, if any field has any error.

Ideally I know which component has an error, so that I can print meaningful comments.

about 4 years ago ยท Juan Pablo Isaza
2 answers
Answer question

0

The groupedErrorValueBool state would need to be in your parent component then, then you give the state handler to the children

const InputField = ({ validation, setGroupErrorBool }) => {
  const [value, setValue] = useState("");
  const [error, setError] = useState(false);

  const handleChange = (e) => {
    let errors = 0;

    if (validation.includes("required") && val === "") {
      errors++;
    }

    if (errors > 0) {
      setError(true);
      setGroupErrorBool(true);
    } else {
      setError(false);
    }
    setValue(e.target.value);
  };

  return <input type="text" value={value} onChange={handleChange} />;
};

const Parent = () => {
  const [groupErrorBool, setGroupErrorBool] = useState(false);
  return (
    <>
      <InputField validation="required" setGroupErrorBool={setGroupErrorBool} />
      <InputField validation="required" setGroupErrorBool={setGroupErrorBool} />
      <button disabled={groupErrorBool}>Submit</button>
    </>
  );
};

Form stuff is admittedly can be very difficult. That's why I use "Formik" for my React forms. Formik I believe will use a parent/overarching form control element with rendered props technique to expose form state handlers, which could also be something you can try yourself

about 4 years ago ยท Juan Pablo Isaza Report

0

Implementation

You could do it like this:

const InputField = ({validation, onErrorChanged}) => {
  const [value, setValue] = React.useState("test");
  const [error, setError] = React.useState(false);

  const handleChange = (e) => {
    let errors = 0;
    
    if (validation.includes("required") && e.target.value === "") {
      errors++;
    }
    if (errors > 0 && !error) {
      // we have error(s) and the error state is set to false
      setError(true);
      onErrorChanged(true);
    } else if (errors === 0 && error){
      // we don't have any error but the error state is set to true
      setError(false);
      onErrorChanged(false);
    }
    setValue(e.target.value)
  }

  return (
    <input
      type="text"
      value={value}
      onChange={handleChange}
    />
  );
};

const InputGroup = () => {
  const [errors, setErrors] = React.useState(0);

  function errorChanged(hasError){
    if(hasError) setErrors(errors + 1);
    else setErrors(errors - 1);
  }

  return (
    <React.Fragment>
      <InputField validation="required" onErrorChanged={errorChanged}/>
      <InputField validation="required" onErrorChanged={errorChanged}/>
      <InputField validation="required" onErrorChanged={errorChanged}/>
      <button disabled={errors === 0 ? false: true}>Submit</button>
    </React.Fragment>
  );
}

ReactDOM.render(<InputGroup/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>

<div id="root"></div>

Explanation

Child component

You need to pass a callback function to the children that is called whenever the error state changes on a child element i. e.

  • when we have found an error in the input and error state is currently set to false
  • when we have no error(s) in the input and error state is currently set to true

Parent component

In the parent component we need a state errors which is a counter that counts the number of child component that have errors. Additionally we need to define the above mentioned callback function such that it increments the counter whenever a child component reports it has an error and decrements the counter when a child component reports it has switched to state no error. If the counter equals zero we know we don't have any error in any of our child components, if it's not null we know how many child components have errors.

about 4 years ago ยท Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
ยฉ 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!