ReactHooks

2019-06-13  本文已影响0人  RoyChina
import { useState, useCallback, useRef, useEffect } from "react";

/**
 * use previous value state
 */
export function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}

/**
 * auto handle the event and update to state
 * can be use in input,textarea... and any other can get value by event.target.value
 * @param {any} initialState
 * @returns {Array} [value, handleChange, reset]
 */
export const useInput = (initialState = "") => {
  const [value, setValue] = useState(initialState);
  const handleChange = event => {
    setValue(event.target.value);
  };
  const reset = newValue => {
    setValue(newValue || initialState);
  };
  return [value, handleChange, reset];
};

/**
 *
 * @param {Object} mapHandler events group by keyCode
 * @example () => {
 *  const =[onKeyEvent] =  useKeyEvent({9:handleTabKeyEvent, 13: handleEnterKeyEvent});
 *  return <input onkeyUp={onKeyEvent} />
 * }
 */
export const useKeyEvent = mapHandler => {
  const onKeyEvent = event => {
    const handler = mapHandler[event.keyCode];
    if (handler instanceof Function) {
      handler(event);
    }
  };
  return [onKeyEvent];
};

/**
 * manage modal state and can pass param when showModal & hideModal method
 * @param {Function} showCallback involk when call showModal
 * @param {Function} hideCallback involk when call hideModal
 * @returns {Array} [isOpen, showModal, hideModal]
 */
export const useModal = (showCallback, hideCallback) => {
  const [isOpen, setIsOpen] = useState(false);
  const showModal = useCallback(extraParam => {
    setIsOpen(true);
    if (showCallback && extraParam !== undefined) {
      showCallback(extraParam);
    }
  });
  const hideModal = useCallback(extraParam => {
    setIsOpen(false);
    if (hideCallback && extraParam !== undefined) {
      hideCallback(extraParam);
    }
  });
  return [isOpen, showModal, hideModal];
};

/**
 * compomentDidUpdate in stateless component and depends on arg "deps"
 * @param {Function} effect
 * @param {Array} deps
 */
export const useDidUpdate = (effect, deps) => {
  const isInitialMount = useRef(true);
  useEffect(
    isInitialMount.current
      ? () => {
          isInitialMount.current = false;
        }
      : effect,
    deps
  );
};

/**
 * Auto toggle class
 * @param {String} cls
 * @param {Boolean} showOnInit
 * @returns [className, setClassNameFlag<Boolean>]
 * @example () => {
 *  const =[isLoading, setIsLoading] =  useToggleClass("loading");
 *  return <botton className={`btn ${isLoading}`} />
 * }
 */
export const useToggleClass = (cls, showOnInit) => {
  const [className, setClassName] = useState(showOnInit ? cls : "");
  return [
    className,
    flag => {
      setClassName(flag ? cls : "");
    },
  ];
};

上一篇下一篇

猜你喜欢

热点阅读