'REACT - Boolean flag if a condition is valid using Regex

I want to set a boolean flag if the proof text contains a valid URL in it. I'm using Regex (http:// or https:// or www. are valid urls)

const TabContent = ({ name, typeProof }) => {
  const [text, setText] = useState("");
  const [proof, setProof] = useState("");
  const [inputURL, setInputURL] = useState("");
  const [valid, setValid] = useState("false");
  const isValidURLRegex =
    "([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+@)?([a-zA-Z0-9.-]+\\.[A-Za-z]{2,4})(:[0-9]+)?(/.*)?";

  // http:// or https:// or www. should work
  const validateURL = (value) => {
    if (!isValidURLRegex.test(value)) {
      setValid(false);
    } else {
      setValid(true);
    }
  };

  function onChange(e) {
    setInputURL(e.target.value);
    validateURL(e.target.value);
  }
  return (
    <>
      <SafeAreaView>
        <TextInput
          style={{
            height: 50,
            margin: 12,
            borderWidth: 0.5,
            padding: 10,
            borderRadius: "10px"
          }}
          placeholder="Enter your proof here:"
          multiline={true}
          onChangeText={(value) => setProof(value)}
          value={proof}
          error={inputURL}
          onChange={() => setInputURL((error) => !error)} // or  onChange={onChange}
        />
      </SafeAreaView>
    </>
  );
};

export default function Tabs({ data }) {
  return (
    <TabsComponent forceRenderTabPanel>
      ...
      </TabList>
      {data.map(({ name, typeProof }) => (
        <TabPanel key={name}>
          <TabContent {...{ name, typeProof }} />
        </TabPanel>
      ))}
    </TabsComponent>
  );
}

Here is my code



Solution 1:[1]

I suggest you using URL to check if URL is valid, instead of RegExp parsing:

const checkIsValidUrl = (url: string): boolean => {
  try {
    new URL(url);
    return true;
  } catch {
    return false;
  }
};

And then you can use it in React component:

const isValidUrl = checkIsValidUrl(inputURL);

You can also memoize it, but it is a premature optimization, which is not suggested.

const isValidUrl = useMemo(() => checkIsValidUrl(inputURL), [inputURL]);

If you want to allow http and https protocols only, you can update the utility this way:

const checkIsValidUrl = (url: string): boolean => {
  try {
    const { protocol } = new URL(url);
    return protocol === 'https:' || protocol === 'http:';
  } catch {
    return false;
  }
};

If you really want to keep the flag in state, then you should use an effect:

useEffect(() => {
  const isValidUrl = checkIsValidUrl(inputURL);
  setValid(isValidUrl);
}, [inputURL]);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1