Site icon NodeXperts

What is React Hooks

React hooks are a type of function that allows the users to hook into react state and life-cycle features from function components. React provides built-in hooks like useState, useEffect, useReducer, useRef, use Callback, useContext, useMemo and we can also create your own custom hooks.

React hooks are available from react version 16.8. Before the introduction of hooks, state can be maintained only in-class components, not in functional components. After the introduction of hooks, state can be maintained in functional components too.

The idea of using hooks makes it possible to create full-fledged functional components, while using all the React features. This allows us to make everything easier, unlike classes.

The main problems which were solved by release of hooks in React 16.8:

In ReactJS, the most difficult thing is to reuse logic in stateful components. Before the appearance of React hooks, there was no way to reuse the logic of behavior to the component, for example, to connect it to the store.

The following examples make it clear why hooks are useful.

Using Classes :

import React, { Component } from ‘react’;

class App extends Component {

constructor(props) {

super(props);

this.state = {

isButtonClicked: false,

}

this.handleClick = this.handleClick.bind(this);

}

handleClick() {

this.setState((prevState) => ({

isButtonClicked: !prevState.isButtonClicked,

}));

}

Using Hooks :

import React, { useState } from ‘react’;

const App = () => {

const [isButtonClicked, setIsButtonClickedStatus] = useState(false);

return (

<button

onClick={() => setIsButtonClickedStatus(!isButtonClicked)}

>

{isButtonClicked ? ‘Clicked’ : ‘Click me, please’}

</button>

);

};

From this, we can understand that hooks work similarly to such concepts as a state.

Rules of Using React Hooks

Hooks are just JavaScript functions, but they require two specific rules:

What is Custom Hooks

Custom Hook is a JavaScript function which we create by ourselves, when we want to share logic between other JavaScript functions. It allows you to reuse some piece of code in several parts of your app.

Advantages and disadvantages

The “useContext” hook has been a blessing for greatly improving the readability of JSX as it allows context values to be read outside of JSX. This was also previously possible in class components by using the static “contextType” property but is even cleaner with “useContext”.

Aside from the code being easier to read it is also much easier to read the component tree in the React dev tools when debugging. The value of this really adds up for components which previously used multiple nested contexts.

With class components the setup and teardown of side effects were split across multiple lifecycle methods like the event listeners could be added in “componentDidMount” and later removed in “componentWillUnmount”. If any component has multiple side effects this could lead to less readable code with a related logic split across several incohesive lifecycle methods.

But the “use Effect” solves this problem by handling both the setup and teardown of side effects. It does so by allowing the effect function to return a function to teardown the effect. It is evident from the below example:

useEffect(() => {

window.addEventListener(“resize”, resizeHandler);

return () =>

window.removeEventListener(“resize”, resizeHandler);

}, []);

Custom hooks are considerably a great mechanism for sharing logic across various components. A custom hook is simply a function which uses one or more React hooks and it can be called within a functional component, just like a standard hook.

A nice example is a custom hook for tracking the result of a media query and returning this state to the component. It demonstrates how hooks can be combined. It uses “useEffect” to set up an event listener to track changes in whether a media query is matched or not. It also uses “useState” to store this state and return the result to the calling component.

function use MatchMedia(mediaQuery) {

const [matches, setMatches] = useState(window.matchMedia(mediaQuery).matches);

useEffect(() => {

const updateMatches = event => {

setMatches(event.matches);

};

const mediaQueryList = window.matchMedia(mediaQuery);

setMatches(mediaQueryList.matches);

mediaQueryList.addListener(updateMatches);

return () => mediaQueryList.removeListener(updateMatches);

}, [mediaQuery]);

return matches;

}

import React, { useState } from ‘react’;

export const useTextField = name => {

const [value, setValue] = useState(”);

const onChange = event => {

setValue(event.target.value);

};

return {

name,

value,

onChange,

placeholder: name,

};

};

const InputDemoWithHooks = () => {

const nameField = useTextField(‘name’);

return <input type=”text” {…nameField} />;

};

export default InputDemoWithHooks;

And tests for the hook:

import React from ‘react’;

import { mount } from ‘enzyme’;

const TestHook = ({ callback }) => {

callback();

return null;

};

export const testHook = (callback) => {

mount(<TestHook callback={callback} />);

};

// tests

import { act } from ‘react-dom/test-utils’;

import { testHook } from ‘./testUtils’;

import { useTextField } from ‘../InputDemoWithHooks’;

let nameField;

beforeEach(() => {

testHook(() => {

nameField = useTextField(‘name’);

});

});

describe(‘useTextField’, () => {

test(‘should have an onChange function’, () => {

expect(nameField.onChange).toBeInstanceOf(Function);

});

test(‘should have correct name’, () => {

expect(nameField.name).toBe(‘name’);

});

test(‘should update the value when onChange is called’, () => {

act(() => {

nameField.onChange({ target: { value: ‘nitin’ } });

});

expect(nameField.value).toBe(‘nitin’);

});

});

// example class component that we will rewrite as function component

class Form extends React.Component {

constructor(props) {

super(props);

this.saveToDraft = debounce(500, this.saveToDraft);

};

state = {

// Fields values

fields: {},

// Draft saving meta

draft: {

isSaving: false,

lastSaved: null,

},

};

saveToDraft = (data) => {

if (this.state.isSaving) {

return;

}

this.setState({

isSaving: true,

});

makeSomeAPICall().then(() => {

this.setState({

isSaving: false,

lastSaved: new Date(),

})

});

}

componentDidUpdate(prevProps, prevState) {

if (!shallowEqual(prevState.fields, this.state.fields)) {

this.saveToDraft(this.state.fields);

}

}

render() {

return (

<form>

{/* Draft saving meta render */}

{/* Inputs render */}

</form>

);

};

}

And the same component as above rewritten as function component

// the above class component rewritten as function component,

const Form = () => {

// Our state

const [fields, setFields] = useState({});

const [draftIsSaving, setDraftIsSaving] = useState(false);

const [draftLastSaved, setDraftLastSaved] = useState(false);

useEffect(() => {

const id = setTimeout(() => {

if (draftIsSaving) {

return;

}

setDraftIsSaving(true);

makeSomeAPICall().then(() => {

setDraftIsSaving(false);

setDraftLastSaved(new Date());

});

}, 500);

return () => clearTimeout(id);

}, [fields]);

return (

<form>

{/* Draft saving meta render */}

{/* Inputs render */}

</form>

);

}

example reusable logic for liking posts on a feed implemented as HOC,

And the same logic rewritten with use of hooks:

componentDidMount rewritten for React Hooks,

comparison between minification of class component and function component that uses hooks.

React Hooks vs older approaches for reusable logic

Mixins are deprecated API. HOCs disadvantage is they create additional DOM elements so when you use few HOCs, then you will see your component nested in few DOM elements. Render props if nested are creating similar structures as “callback hell” in the past. Hooks have no disadvantages of using multiple custom hooks on a single component.

When and How to Use

When we want to share the logic between other components, we can extract it to a separate function. According to official documents, the custom hook has to:

Because custom hook is a JS function, the Rules of Hooks apply to it as well. Those are:

Disadvantages

Limitations

Name:- npm i stack-ui-hooks

  1. useArray
  2. useSet
  3. useMap
  4. useList
  5. useBoolean
  6. useNumber
  7. useCheckbox
  8. useActive
  9. useAsync
  10. useBind
  11. useDidMount
  12. useDidUpdate
  13. useClickOutside
  14. useDelay
  15. useDocumentReady
  16. useFocus
  17. useGoogleAnalytics
  18. useImage
  19. useInput
  20. useLogger
  21. useOnclick
  22. usePageLoad
  23. usePersist
  24. usePrevious
  25. usePersist
  26. useScript
  27. useWindowSize
  28. UseActive
  29. UseAsync
  30. UseBind
  31. UseCheckbox
  32. UseCounter
  33. useDidMount
  34. useDidUpdate
  35. useEqualEffect
  36. useFetch
  37. useField
  38. useFocus
  39. useGlobalState
  40. useHover
  41. useMergeState
  42. useNestedBind
  43. useNestedState
  44. useStateCallback
  45. useToggle
  46. useTouch
  47. useUndo
  48. useWillUnmount
  49. useCounter
  50. useFocus
  51. useInput
  52. useInterval
  53. useLifecycleHooks
  54. useMergeState
  55. useOnMount
  56. useOnUnmount
  57. usePrevius
  58. useTimeout
  59. useAsync
  60. useAsyncFn
  61. useAsyncRetry
  62. useAudio
  63. useBatery
  64. useBeforeUnload
  65. useClickAway
  66. useCookie
  67. useCopyToClipboard
  68. useCounter
  69. useCss
  70. useCustomCompareEffect
  71. useDebounce
  72. useDeepCompareEffect
  73. useDefault
  74. useDrop
  75. useDropArea
  76. useEffectOnce
  77. useEnsuredForwardedRef
  78. useError
  79. useEvent
  80. useFavicon
  81. useFirstMountState
  82. useFullscreen
  83. useGeolocation
  84. useGetSet
  85. useGetSetState
  86. useHarmonicInterval
  87. useHash
  88. useHoverDirty
  89. useIdle
  90. useIntersection
  91. useInterval
  92. useIsomorhicLayoutEffect
  93. useKey
  94. useKeyboardJs
  95. useLatest
  96. useLifecycle
  97. useLocalStorage
  98. useLocation
  99. useLockBodyScroll
  100. useLogger
  101. useLongPress
  102. useMeasure
  103. useMeasureDirty
  104. useMedia
  105. useMediaDevices
  106. useMediatedState
  107. useMethod
  108. useMotion
  109. useMount
  110. useMountedState
  111. useMouse
  112. useMouseWheel
  113. useMultiStateValidator
  114. useNetworkState
  115. useObservable
  116. useOrientation
  117. usePageleave
  118. usePermission
  119. usePrevious
  120. usePreviousDistinct
  121. usePromise
  122. useQueue
  123. useRaf
  124. useRafLoop
  125. useRafState
  126. useRenderCount
  127. useScratch
  128. useScroll
  129. useScrollbarWidth
  130. useScrolling
  131. useSearchParam
  132. useSessionStorage
  133. useSetState
  134. useShallowCompareEffect
  135. useSize
  136. useSlider
  137. useSpring
  138. useStartTyping
  139. useStateList
  140. useStateValidator
  141. useStateWithHistory
  142. useThrottle
  143. useThrottleFn
  144. useTitle
  145. useTween
  146. useUnmount
  147. useUnmountPromise
  148. useUpdate
  149. useUpdateEffect
  150. useUpsert
  151. useVibrate
  152. useVedio
  153. useWait
  154. useWindowScroll
  155. useWindowSize
  156. useAdjustColor
  157. useDarkMode
  158. useEventListner
  159. useDimensions
  160. useFullScreen
  161. useGeoLocation
  162. useLsClient
  163. useKeyPress
  164. useMultiKeyPress
  165. useNotification
  166. useOnClickOutside
  167. useOnlineStatus
  168. usePrevious
  169. usePrint
  170. useQueryParams
  171. useSpeech
  172. useSpeechRecognition
  173. useSpeechSynthesis
  174. useWorker

Website—– like stackui

Lang use —– typescript

Npm package launch

Presentation

Code — private github

Project create reference :-

https://www.smashingmagazine.com/2020/05/typescript-modern-react-projects-webpack-babel/

Exit mobile version