0

I am new to ReactJS Hooks. I searched out for a clear controlled form validation example but didn't get one. So I decided to write a simple question that anyone can easily understand it.

Assume I have a two input fields, type number and type text

const [values, set_values] = useState({first_input:'',second_input:''});

const handle_change = (e) => {
  let name = e.target.name
  let value = e.target.value;
  values[name] = value;
  set_values(values);
}

const test_validation () => {
  // I used to do it this way
  if(document.getElementsByName('first_input')[0].value==''){
    alert("first input is required")
  }
}

return(
  <div>
    <input onChange={handle_change} name='first_input' type='number' />
    <input onChange={handle_change} name='second_input' type='text' />

    <input type='submit' onClick={test_validation} />
  <div/>
)

Is it wrong to use pure JS to check the input's value and set conditions or is it preferred to use React validation forms?

I tried to set required attribute on input element tag so it can't be skipped but didn't work.

I need to alert() warning message for the required filed or highlight or focus on it.

1
  • 1
    @tksilicon he seems to have a pretty solid variable naming style convention that he's sticking to. It may be against YOUR convention, but YOUR way isn't THE way. document.getElementById is JS so it should work fine, although I can agree that part isn't a very good practice. Commented Apr 25, 2020 at 22:42

3 Answers 3

2

Firstly, your update function isn't really working as it should.

Try this instead:

const handle_change = (e) => {
  let name = e.target.name
  let value = e.target.value;
  set_values({ ...values, [name]: value });
}

Then the better practice here is to make your <input /> elements controlled components.

Eg for first_input do this:

<input onChange={handle_change} name='first_input' type='number' value={values.first_input} />

Then your validation could look like this:

const test_validation () => {
  if(values.first_input === ''){
    alert("first input is required")
  }
}

This should successfully trigger the alert you were hoping for when the value is still an empty string.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you, this worked, please consider up-voting the question so it can reach out for those who have similar issues
2

Your method of updating input values in the handle_change function is wrong. Values is a constant and cannot be modified directly. Use the ES6 spread operator with set_values to update the values.

set_values({...values, [name]:value});

Comments

2

Here is a minimal example about how to handle validation:

Most of the time, you won't need to directly manipulate DOM API with React. Also make sure you do an e.preventDefault when you validate, otherwise the event will propagate due to event bubbling

import React, { useState } from "react";

export default function App() {
  const [values, setValues] = useState({ numberInput: "", textInput: "" });

  const validation = e => {
    if (values.numberInput === '' || !values.textInput) {
      e.preventDefault();
      alert("numberInput and textInput are required");
    }
  };

  return (
    <div>
      <form
        onSubmit={e => {
          e.preventDefault();
          alert("submit ");
        }}
      >
        <input
          onChange={({ target }) => setValues({ numberInput: target.value })}
          name="numberInput"
          type="number"
        />
        <input
          onChange={({ target }) => setValues({ textInput: target.value })}
          name="textInput"
          type="text"
        />

        <input type="submit" onClick={validation} />
      </form>
    </div>
  );
}

5 Comments

if (!values.numberInput || values.textInput) translates to "if numberInput is undefined" OR "if textInput exists (even as an empty string)", "then do something".
Concerning e.preventDefault() if the form validation is ok we should just propagate the event. I guess
That still doesn't cut it. Because !values.numberInput is not the same as values.numberInput.length > 0. !values.numberInput checks if values.numberInput is undefined. In this case, values.numberInput is '' (an empty string), which is NOT undefined.
Fair enough you're correct about the e.preventDefault().
tl:dr; This is what you want: if (values.numberInput === '' || values.textInput === "")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.