Playing with React Hooks
Even though I write a fair bit of React code in my day to day, it tends to be within a system that is currently “frozen” at version 16.5.2… meaning Hooks aren’t an option at the minute.
So when working on a side project, I jumped at the chance to work in some custom hooks where possible!
Some simple validation
So I had a simple form with a few fields, and the need to validate one of them to ensure it only contained alphanumeric characters and hyphens. I then set this isValid
value to local state, showing a validation message if something funky has crept in.
(It’s worth saying at this point I could just use Formik here but my forms are so simple I thought I’d stay off npm
for now :)
So the first pass using the useState
hook looked something like this:
const slugRegex = new RegExp(/^([a-z0-9\-]*)$/);
const [validSlug, setValidSlug] = useState(true);
function validateSlug(updatedSlug) {
const isSlugValid = slugRegex.test(updatedSlug);
setValidSlug(isSlugValid);
}
function onChange(e) {
validateSlug(e.target.value);
}
So far, so contrived :) Although given I have more than one place I needed to use the validation, it felt like an opportunity to “hookify” the code!
Time for the Hook
As per the React advice I started out with a function prefixed with the word “use” and moved the state and the validator function inside:
import { useState } from "react";
const SlugRegEx = new RegExp(/^([a-zA-Z0-9\-]*)$/);
export const useSlugValidation = (initialValue) => {
const [isValidSlug, setIsValidSlug] = useState(initialValue);
const validateSlug = (slug) => {
const isValid = SlugRegEx.test(slug);
setIsValidSlug(isValid);
};
return [isValidSlug, validateSlug];
};
Then using it was pretty straightforward:
const [isValidSlug, validateSlug] = useSlugValidation(true);
function onChange(e) {
validateSlug(e.target.value);
}
function updateCurrentPost() {
if (!isValidSlug) {
console.log("Unable to save post - correct the slug!");
return;
}
}
And that’s it! Of course I could add additional validation rules, and can see how I might make the whole thing more generic. But as a simple refactor I’m happy enough :)