DEV Community

loading...
Cover image for πŸ…³πŸ†πŸ†ˆ-πŸ…ΎπŸ…½-πŸ†πŸ…΄πŸ…°πŸ…²πŸ†ƒ πŸŽ‰

πŸ…³πŸ†πŸ†ˆ-πŸ…ΎπŸ…½-πŸ†πŸ…΄πŸ…°πŸ…²πŸ†ƒ πŸŽ‰

filoscoder profile image Wonjang Son ・2 min read

πŸ…³πŸ†πŸ†ˆ-πŸ…ΎπŸ…½-πŸ†πŸ…΄πŸ…°πŸ…²πŸ†ƒ πŸŽ‰

Hi, I've just opened a public space to build up a useful collection of helper functions for ordinary and concurrent daily problems.

I'm a freelance Software Engineer, my stack is Javascript & React. After some time working on different projects, I found myself facing the same problems and solving them with the same pattern. This is a repository for saving valuable time and stay as DRY as possible while working.

This open-source has his goal on stay as πŸ„³πŸ…πŸ…ˆ (Don't Repeat Yourself) as possible.

Example 1: phoneMask

How many times do I have to write a function to mask/format a mobile phone number input????

This is how I implemented πŸ‘‡

// Parameter> $inputValue: string
// Output> "xxx-xxxx-xxxx"
export const phoneMask = (inputValue = "") =>
  inputValue
    .replace(/\D/g, "")
    .replace(/(\d{1,3})(\d{1,4})?(\d{1,4})?/g, function (_, a, b, c) {
      return c ? `${a}-${b}-${c}` : b ? `${a}-${b}` : `${a}`;
    });
Enter fullscreen mode Exit fullscreen mode

Example 2: useInputs

How do you handle user input changes on React? Still using the obvious useState?
I write a custom hook to handle user input changes trying to be clean on implement and effective at the same time.

This is how I implemented itπŸ‘‡ (Typescript + React hooks)

import React, { useCallback, useReducer } from "react";

type DefaultValues = {
  [key: string]: string;
};
type UseInputsAction = {
  name: string;
  value: string;
};

function reducer<T>(state: T, action: UseInputsAction | null) {
  if (!action) {
    const initialState: any = {};
    Object.keys(state).forEach((key) => {
      initialState[key] = "";
    });

    return initialState;
  }

  return {
    ...state,
    [action.name]: action.value,
  };
}

export default function useInputs<T>(defaultValues: DefaultValues) {
  const [state, dispatch] = useReducer(reducer, defaultValues);
  const onChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
      dispatch({
        name: e.target.name,
        value: e.target.value,
      });
    },
    []
  );
  const onReset = useCallback(() => {
    dispatch(null);
  }, []);

  return [state, dispatch, onChange, onReset] as [
    T,
    typeof dispatch,
    typeof onChange,
    typeof onReset
  ];
}

/*

# Usage
import { useInputs } from "./dry";

.
.
.
// React component
const [form, onChange] = useInputs<MyFormType>({
    email: '',
    password: '',
});
.
.
.
// Render => Form JSX
<form>
  <input 
    type="email"
    name="email"
    value={form.email}
    onChange={onChange}
  />
  <input
    type="password"
    name="password"
    value={form.password}
    onChange={onChange}
  />
</form>

*/
Enter fullscreen mode Exit fullscreen mode

SAME CODE to solve SAME PROBLEMS?

Contribute your grain of codeπŸ‘‡

DRY-001

Discussion (1)

Collapse
0916dhkim profile image
Donghyeon Kim • Edited

I usually rely on 3rd party libraries (either use them directly or write code heavily inspired by their implementation). One example would be react-hook-form package for your usecase 2.

react-hook-form equivalent of your code:

function App() {
  const { register, handleSubmit } = useForm();
  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('email')} />
      <input {...register('password')} />
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

Also, phone number formatting is not worth doing it DIY IMO. For example, your code is for 11-digit phone numbers, but Americans use 10-digit phone numbers. What about international numbers with + prefix? Obviously the list goes on, and it is really difficult to get it right.

Forem Open with the Forem app