• 18-19 College Green, Dublin 2
  • 01 685 9088
  • info@cunninghamwebsolutions.com
  • cunninghamwebsolutions
    Cunningham Web Solutions
    • Home
    • About Us
    • Our Services
      • Web Design
      • Digital Marketing
      • SEO Services
      • E-commerce Websites
      • Website Redevelopment
      • Social Media Services
    • Digital Marketing
      • Adwords
      • Social Media Services
      • Email Marketing
      • Display Advertising
      • Remarketing
    • Portfolio
    • FAQ’s
    • Blog
    • Contact Us
    MENU CLOSE back  

    Creating Your Own React Validation Library: The Developer Experience (Part 3)

    You are here:
    1. Home
    2. Web Design
    3. Creating Your Own React Validation Library: The Developer Experience (Part 3)
    Thumbnail for 23072
    Smashing Editorial

    Creating Your Own React Validation Library: The Developer Experience (Part 3)

    Creating Your Own React Validation Library: The Developer Experience (Part 3)

    Kristofer Selbekk

    2019-05-30T13:00:59+02:00
    2019-05-30T12:35:25+00:00

    If you’ve been following along this little article series, you’ve now learned how to put together your very own validation library. It can handle almost any challenge you can throw at it, and it even helps out with accessibility concerns! Its only downfall is that it sucks to work with.

    Yep, that’s right. The user experience from a developer point of view is seriously lacking. We don’t get any helpful warnings when we misspell words, misuse APIs or, well, anything, really!

    This article will guide you through how you can improve the developer experience of your validation library — or any library for that sake.

    • Part 1: The Basics
    • Part 2: The Features
    • Part 3: The Experience

    Starting Out

    Since the last part of this article, we’ve pulled out all library code into its own files. Take a look at the CodeSandbox demo to see what we’re starting out with.

    Convenience Functions

    We want our library to be as simple as possible to use for the most common cases. A way to move towards that goal is to add convenient utility functions for certain functionality.

    One such feature could be to check if our form is valid — that is, if all error messages are null. This is something you typically check in your onSubmit handler, but it could be useful in your render-method too. Let’s implement it!

    const isFormValid = useMemo(
      () => Object.values(errors).every(error => error === null), 
      [errors]
    );
    

    We’ll provide this flag in our onSubmit form handler, as well as in our render method.

    • See CodeSandbox demo

    There are plenty more of these that could be written, but I’ll let that be an exercise for the reader.

    Development Warnings And Invariants

    One of React’s greatest features is its many helpful console warnings while developing. We should provide the same sort of quality to our users as well.

    To get started, we’ll create two functions — warning for logging warnings to the console, and invariant for throwing an error — both if a given condition is not met.

    function warning(condition, message) {
      if (process.env.NODE_ENV === 'production' || condition) {
        return;
      }
    
      console.warn('useValidation: ' + message);
    }
    function invariant(condition, message) {
      if (process.env.NODE_ENV === 'production' || condition) {
        return;
      }
    
      throw new Error('useValidation: ' + message);
    }
    

    You want to use invariant if the error is going to crash your library (or render it useless), and warning for bad practices or other advice.

    When To Warn

    Deciding when to warn is pretty important. Too many, and you’re just annoying. Too few, and you let critical bugs ship to production. Therefore, we need to be smart with our warnings.

    Since our library accepts a pretty large configuration object, it makes sense to validate this somehow — at least while developing. We could solve it by using a type system like TypeScript or Flow, but that excludes all regular ol’ JavaScript users.

    Instead, let’s create a runtime schema checker, where we validate that the config contains the correct fields, and print relevant warnings.

    function validateConfigSchema(config) {
      if (process.env.NODE_ENV === 'production') {
        return;
      }
      if (typeof config === 'function') {
        config = config({});
      }
    
      invariant(
        typeof config === 'object',
        `useValidation should be called with an object or a function returning an object. You passed a ${typeof config}.`,
      );
    
      invariant(
        typeof config.fields === 'object',
        'useValidation requires a `field` prop with an object containing the fields and their validators. Please refer to the documentation on usage: https://link.to/docs'
      );
    
      
      invariant(
        Object.values(config.fields).every(field => typeof field === 'object'),
        'useValidation requires that the `field` object only contains objects. It looks like yours isn't. Please refer to the documentation on usage: https://link.to/docs'
      );
    
      warning(
        ['always', 'blur', 'submit', undefined].includes(config.showError),
        'useValidation received an unsupported value in the `showError` prop. Valid values are "always", "blur" or "submit".'
      )
    
      // And so on
    }
    

    We could probably go on doing this for a while if we wanted to spend the time. And you should! It’s a great way to improve the developer experience of your app.

    You don’t have to be writing these by hand, however. There’s a browser-port of the popular object schema validation library joi that could help out with creating a really nice runtime validation check. Also, as previously mentioned, a type system would help catch configuration errors at compile time for the users that use that type system.

    Allow For Flexibility

    A good developer experience is in large part not getting in the way of the developers. Let’s look at a few ways we can improve that experience.

    Compose Conflicting Props

    First, our prop getters apply some props to our inputs and forms that can be accidentally overridden by our consumers. Instead, let’s add a prop override object to our prop getters, which will compose any conflicting props together.

    Here’s how we can implement this in our getFieldProps:

    
    getFieldProps: (fieldName, overrides = {}) => ({
      onChange: e => {
        const { value } = e.target;
        if (!config.fields[fieldName]) {
          return;
        }
        dispatch({
          type: 'change',
          payload: { [fieldName]: value },
        });
        if (overrides.onChange) {
          overrides.onChange(e);
        }
      },
      onBlur: e => {
        dispatch({ type: 'blur', payload: fieldName });
        if (overrides.onBlur) {
          overrides.onBlur(e)
        }
      },
      name: overrides.name || fieldName,
      value: state.values[fieldName] || '',
    }),
    

    A similar approach can be followed in getFormProps.

    Help Avoid Prop Drilling

    Some forms might be large and split up into several components. Instead of making our consumers’ drill props down the tree, we should provide a context. This way, they can access all the stuff we return from our custom hook anywhere in the tree below.

    First, let’s create a ValidationContext with React’s createContext method:

    export const ValidationContext = React.createContext({});
    

    Next, let’s create a component ValidationProvider, that provides all the values from the useValidation hook in context instead:

    export const ValidationProvider = props => {
      const context = useValidation(props.config);
      return (
        
          {props.children}
        
      );
    };
    

    Now, instead of calling useValidation directly, we’d wrap our form in a ValidationProvider component, and get access to the validation props (getFormProps, errors etc) by use of the useContext hook. You’d use it like this:

    Import React, { useContext } from 'react';
    import { ValidationContext } from './useValidation';
    
    function UsernameForm(props) {
      const { getFieldProps, errors } = useContext(ValidationContext);
      return (
        <>
          <input {...getFieldProps('username')} />
          {errors.username && {errors.username}></span>}
        </>
      );
    }
    

    This way, you get the best of both worlds! You get a simple hook for those simple scenarios, and you get the flexibility you need for those complex parts.

    Documentation Is Key 🔑

    Whenever I’m using a library I didn’t write myself, I love great documentation. But what should you focus on, and where should you document?

    A first step should be to put together a simple to understand README, with the most basic usage examples readily available. Andrew Healey wrote an amazing piece on how to write a good README, which I highly recommend you read.

    When you’ve created a good README to get people going, a documentation website might be a good idea. Here, you can put a more in-depth API documentation, recipes for typical use cases and a good ol’ FAQ.

    There are great tools out there for generating documentation websites. My favorite is docusaurus from Facebook (humble brag: we used it when creating the create-react-app website), but there are several good alternatives out there.

    We’re not going to go through how to write good documentation in this article. There are several good articles out there — even a community called “Write the Docs”. They have written a great guide to how you can get started with writing great documentation.

    Summary

    Through this article series, we’ve created a pretty decent validation library. It has a pretty simple API, flexibility for when you need it, a good developer experience, and a lot of pretty dank features.

    We’ve gone through how we implemented things step by step, and I hope you got a deeper understanding of how you can make your own library, and how you make it something people would love to use.

    Please let me know in the comments what you think, and if there were some parts you got stuck on or had a hard time understanding. I’ll try my best to update the article as feedback trickles in.

    To end this article off — here’s the final version:

    • See CodeSandbox demo

    Thanks for reading!

    (dm, yk, il)

    From our sponsors: Creating Your Own React Validation Library: The Developer Experience (Part 3)

    Posted on 30th May 2019Web Design
    FacebookshareTwittertweetGoogle+share

    Related posts

    Archived
    22nd March 2023
    Archived
    18th March 2023
    Archived
    20th January 2023
    Thumbnail for 25788
    Handling Continuous Integration And Delivery With GitHub Actions
    19th October 2020
    Thumbnail for 25778
    A Monthly Update With New Guides And Community Resources
    19th October 2020
    Thumbnail for 25781
    Supercharge Testing React Applications With Wallaby.js
    19th October 2020
    Latest News
    • Archived
      22nd March 2023
    • Archived
      18th March 2023
    • Archived
      20th January 2023
    • 20201019 ML Brief
      19th October 2020
    • Thumbnail for 25788
      Handling Continuous Integration And Delivery With GitHub Actions
      19th October 2020
    • Thumbnail for 25786
      The Future of CX with Larry Ellison
      19th October 2020
    News Categories
    • Digital Marketing
    • Web Design

    Our services

    Website Design
    Website Design

    A website is an important part of any business. Professional website development is an essential element of a successful online business.

    We provide website design services for every type of website imaginable. We supply brochure websites, E-commerce websites, bespoke website design, custom website development and a range of website applications. We love developing websites, come and talk to us about your project and we will tailor make a solution to match your requirements.

    You can contact us by phone, email or send us a request through our online form and we can give you a call back.

    More Information

    Digital Marketing
    Digital Marketing

    Our digital marketeers have years of experience in developing and excuting digital marketing strategies. We can help you promote your business online with the most effective methods to achieve the greatest return for your marketing budget. We offer a full service with includes the following:

    1. Social Media Marketing

    2. Email & Newsletter Advertising

    3. PPC - Pay Per Click

    4. A range of other methods are available

    More Information

    SEO
    SEO Services

    SEO is an essential part of owning an online property. The higher up the search engines that your website appears, the more visitors you will have and therefore the greater the potential for more business and increased profits.

    We offer a range of SEO services and packages. Our packages are very popular due to the expanse of on-page and off-page SEO services that they cover. Contact us to discuss your website and the SEO services that would best suit to increase your websites ranking.

    More Information

    E-commerce
    E-commerce Websites

    E-commerce is a rapidly growing area with sales online increasing year on year. A professional E-commerce store online is essential to increase sales and is a reflection of your business to potential customers. We provide professional E-commerce websites custom built to meet our clients requirements.

    Starting to sell online can be a daunting task and we are here to make that journey as smooth as possible. When you work with Cunningham Web Solutions on your E-commerce website, you will benefit from the experience of our team and every detail from the website design to stock management is carefully planned and designed with you in mind.

    More Information

    Social Media Services
    Social Media Services

    Social Media is becoming an increasingly effective method of marketing online. The opportunities that social media marketing can offer are endless and when managed correctly can bring great benefits to every business.

    Social Media Marketing is a low cost form of advertising that continues to bring a very good ROI for our clients. In conjuction with excellent website development and SEO, social media marketing should be an essential part of every digital marketing strategy.

    We offer Social Media Management packages and we also offer Social Media Training to individuals and to companies. Contact us to find out more.

    More Information

    Cunningham Web Solutions
    © Copyright 2025 | Cunningham Web Solutions
    • Home
    • Our Services
    • FAQ's
    • Account Services
    • Privacy Policy
    • Contact Us