React Input Component Validate Zip Code
Today I wanted to share a react snippet for Zip Code validation within an input.
The full example of the code is all the way at the bottom, but first I wanted to share a list of all the things this example gets into.
- A Reusable React Input Component
- Input handling (keydown, keyup, and paste events)
- Numeric keyboard on input focus when using mobile devices
- Utility function helpers
- Local storage- Initial React application state
- Updating application state upon local storage being set
 
Reusable React Component
Below is the boilerplate Input component and how to implement it:
import React, { Component } from "react";
// component
class Input extends Component {
  // default props for input
  static defaultProps = {
    onInput: "",
    onKeyDown: "",
    onKeyUp: "",
    // this is an example of removing the paste
    // functionality entirely across the board
    // onPaste: (e) => { e.preventDefault() },
    onPaste: "",
    max: "",
    min: "",
    inputmode: "",
    pattern: "",
    placeholder: "",
    type: "text"
  };
  render() {
    return (
      <input
        inputMode={this.props.inputmode}
        max={this.props.max}
        min={this.props.min}
        onInput={e => {
          this.props.onInput === "" ? "" : this.props.onInput(e);
        }}
        onKeyDown={e => {
          this.props.onKeyDown === "" ? "" : this.props.onKeyDown(e);
        }}
        onKeyUp={e => {
          this.props.onKeyUp === "" ? "" : this.props.onKeyUp(e);
        }}
        onPaste={e => {
          this.props.onPaste === "" ? "" : this.props.onPaste(e);
        }}
        pattern={this.props.pattern}
        placeholder={this.props.placeholder}
        type={this.props.type}
        defaultValue={this.props.value}
      />
    );
  }
}
export default Input;Input handling
Next we want to take a look at the input handling functions:
handleZipcodeInputKeyDown = e => {
  // this is called as soon as we get input from the user
  // we don't want to allow them the access to input past 5 digits
  // so we block on keyDown
  // (it never gets to keyUp, which actually updates the state)
  // restrict to 5 digits only
  // but allow backspace and arrow
  var key = e.which ? e.which : e.keyCode;
  if (
    (e.target.value.length >= 5 &&
      key !== 8 &&
      key !== 37 &&
      key !== 38 &&
      key !== 39 &&
      key !== 40) ||
    (key === 18 || key === 189 || key === 229)
  ) {
    e.preventDefault();
  }
};
handleZipcodeInputKeyUp = e => {
  // set state of zipcode
  this.setState({
    zipCode: e.target.value
  });
};
handleZipcodeInputPaste = e => {
  e.preventDefault();
  // get pasted content
  let pasteText = e.clipboardData.getData("text/plain");
  // only allow integers
  pasteText = pasteText.replace(/[^0-9]/g, "");
  // add to current input value (target)
  let newContent = e.target.value + pasteText;
  // only allow 5 digits total
  newContent = newContent.substring(0, 5);
  // set new value of input
  e.target.value = newContent;
  // set new state of zipcode
  this.setState({
    zipCode: newContent
  });
};Numeric keyboard (mobile devices)
Forcing the numeric keyboard on input focus with these lines:
Notice: inputmode, pattern & type props passed to our component.
// put at the top of our App.js file
import Input from "./input";
// put within our render function
<Input
  inputmode="numeric"
  onKeyDown={e => this.handleZipcodeInputKeyDown(e)}
  onKeyUp={e => this.handleZipcodeInputKeyUp(e)}
  onPaste={e => this.handleZipcodeInputPaste(e)}
  pattern="\d*"
  placeholder="Enter zipcode"
  type="number"
  value={this.state.zipCode}
/>Including Utility Helpers and Usage
Include the helper utility for local storage and an example of setting it (on zip code submit).
// put at the top of our App.js file
import { localDataGet, localDataSet, localDataDelete } from "./utilities";
// put within our App.js React highlevel component
handleZipcodeSubmit = () => {
  // store the zip code in local storage
  localDataSet("zipCode", this.state.zipCode);
};Local Storage Load In
Then within our constructor we want to add before the initial state
constructor(props) {
  super(props);
  // local storage call
  const userLocalData = localDataGet();
  // console.log("data from local storage");
  // console.log(userLocalData);
  // initial app state
  this.state = {
    zipCode: userLocalData.zipCode ? userLocalData.zipCode : ""
  };
}