:anchor: A demo app for React Hooks
A demo app for React Hooks.
- A Hook is a special function that lets you “hook into” React state and lifecycle features.
- Hooks are a new addition in React 16.8, which allow you to use state and other React features without writing a class.
- For example, useState is a Hook that lets you add React state to function components. Hooks dont work inside classes
this
keyword and bind this.Complex components become hard to understand.
- Example components might perform some data fetching in
componentDidMount
andcomponentDidUpdate
,- However, the same
componentDidMount
method might also contain some unrelated logic that sets up event listeners, with cleanup performed incomponentWillUnmount
- We can perform all operations in just one hook
useEffect()
, that we used to perform in three different lifecycle methods ComponentDidMount, ComponentWillUnmount and ComponentDidUpdate.- For Example, we can perform all operations (effects) in one hook
useEffect()
, when we want an operation to be performed on every render. In classes we had to do the
same operation in both ComponentDidMount and ComponentDidUpdate.- Lifecycle methods of a class often contain unrelated logic, but related logic gets broken up into several methods.
Unlike componentDidMount or componentDidUpdate, effects scheduled with useEffect don’t block the browser from updating the screen. This makes your app feel more responsive.
function ExampleWithManyStates() {
// Declare multiple state variables!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
// ...
}
useState()
useState
takes initialState and returns a pair ( an array with two items ): the current state value
and a function that lets you update it
const [count, setCount] = useState( initialState );
Calling useState()
like above, declares a state variable (count).The first time our component renders, its value will be equal to initialState.
The next time our component renders its value will be equal to current State ( which will be same as initial state
unless the setCount() updates its value )
When setCount( 1 )
is called with a new value, React re-renders your component, passing new state (count) value to it.
useState
is similar to this.setState in a class, except it doesn’t merge the old and new state together
useEffect()
Operations like data fetching, subscriptions, or manually changing the DOM from React components are called “side effects” or “effects”,
because they can affect other components and can’t be done during rendering.
useEffect
, adds the ability to perform side effects from a function component. It serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount in React classes.
By default, React runs the effects after every render — including the first render. So useEffect()
is called on initial render, when state changes ( component updates ) and when component unmounts.
Just like with useState, you can use more than a single effect in a component
Effects that don't require cleanup
:are the operations we perform after React has updated the DOM ( after render is called ).
For example network request, user login. useEffect takes a function , that can be called ‘effects’ because it performs some operations.
Some of these functions ( effects ), passed as a parameter, might require cleanup so they return a function, which we will discuss below.
useEffect( () => {
console.warn( 'mounted/updated: Do Something( Fetch API, Add Event )' );
} );
Effects that do require cleanup
:are the operations where we may want to set up a subscription to some external data source. So its important
to cleanup to avoid memory leak. If your effect returns a function, React will run it when it is time to clean up on unmounts and re-render. Function return is optional
and is required only if we require cleaning. Please note the this return function is called when the component unmounts and on every re-render.
useEffect( () => {
console.warn( 'mounted/updated: Do Something( Fetch API, Add Event )' );
return () => console.warn( 'unmounted: Do Something( Unsuscribe, Remove Event )' );
} );
Skipping Effect for Perforance Optimization
:You can tell React to skip applying an effect if certain values haven’t changed between re-renders. To do so, pass an array as an optional second argument to useEffect:
In below case if the value of ‘count’( state variable ) does not change then the effect ( function passed as a parameter in useEffect ) will not run.
If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument
useEffect( () => {
console.warn( 'mounted/updated: Do Something( Fetch API, Add Event )' );
return () => console.warn( 'unmounted: Do Something( Unsuscribe, Remove Event )' );
}, [count] );
useConText()
useConText
lets you subscribe to React context without introducing nesting
Create AppContext and AppProvider out of it.
import React, { useState } from 'react';
export const AppContext = React.createContext([
{},
() => {}
]);
export const AppProvider = ( props ) => {
const [ state, setState ] = useState();
return (
<AppContext.Provider value={ [ state, setState ] }>
{ props.children }
</AppContext.Provider>
);
};
Wrap your main component with AppProvider
import { AppProvider } from "../context/AppContext";
const Index = ( props ) => {
return (
<AppProvider>
<div>
<AddToCartButton>
</div>
</AppProvider>
);
};
export default Index;
Then use useContext( AppContext )
in any component to access a global context since <AppProvider>
wrapped your main component above
import { useContext } from 'react';
import { AppContext } from "./context/AppContext";
const AddToCartButton = ( props ) => {
const [ state, setState ] = useContext( AppContext );
const handleAddToCartClick = () => {
setState( 'new cart' );
};
return(
<React.Fragment>
<button onClick={ handleAddToCartClick } className="btn btn-secondary">Add to cart</button>
</React.Fragment>
)
};
useReducer()
useReducer
lets you manage local state of complex components with a reducer useCallback()
useMemo()
useRef()
useImperativeHandle()
useLayoutEffect()
useDebugValue()
“memory cells”
associated with each component. They’re just JavaScript objects where we can put some data.useState()
, it reads the current cell (or initializes it during the first render), and then moves the pointer to the next one.constructor
: Function components don’t need a constructor. You can initialize the state in the useState call.getDerivedStateFromProps
: Schedule an update while rendering instead.render
: This is the function component body itself.componentDidMount
, componentDidUpdate
, componentWillUnmount
: The useEffect Hook can express all combinations of these (including less common cases).componentDidCatch
and getDerivedStateFromError
: There are no Hook equivalents for these methods yet, but they will be added soon.Clone this repo in git clone https://github.com/imranhsayed/react-hooks
cd react-hooks
Run npm install
useState Example:
increment-counter Simple Example for a State Hook useState
, by incrementing counter on click of a button.useState Example:
todo-app Example of creating a Todo App using React HooksuseEffect Example:
hierarchical-components Example for Parent Child Component, where useEffect gets called when Component Mounts or Unmounts.dev
Runs webpack dev server for development ( in watch mode )prod
Runs webpack in production mode