FEWD Unit4
FEWD Unit4
React hooks are a feature introduced in React 16.8 that allow you to use state
and other React features without writing a class component. Before hooks,
state and lifecycle methods were exclusively available to class components.
With hooks, these capabilities became accessible in function components as
well, enabling developers to write more concise and readable components.
1. useEffect
example of `useEffect`:
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
return () => {
This is the cleanup function. It's equivalent to componentWillUnmount in
class components.
In this case, it doesn't do anything, but you might use it to clear timers,
cancel network requests, etc.
};
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
export default Example;
2. `useRef`
It's commonly used to access the DOM directly, but it can also be used to keep
a mutable reference to any value without re-rendering the component.
Example:
return (
<>
<input
ref={inputEl}
value={value}
onChange={e => setValue(e.target.value)}
/>
<button onClick={onButtonClick}>
Focus the input
</button>
</>
);
}
function PreviousValueComponent() {
const [count, setCount] = useState(0);
const prevCountRef = useRef();
useEffect(() => {
prevCountRef.current = count;
}, [count]);
return (
<div>
<h1>Now: {count}, Before: {prevCountRef.current}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default PreviousValueComponent;
2. Tracking IsMounted to Prevent State Updates on Unmounted Components
function TimerComponent() {
const [seconds, setSeconds] = useState(0);
const isMountedRef = useRef(true);
useEffect(() => {
const interval = setInterval(() => {
if (isMountedRef.current) {
setSeconds((prevSeconds) => prevSeconds + 1);
}
}, 1000);
return () => {
isMountedRef.current = false;
clearInterval(interval);
};
}, []);
function IntervalComponent() {
const [count, setCount] = useState(0);
const intervalIdRef = useRef(null);
useEffect(() => {
intervalIdRef.current = setInterval(() => {
setCount((prevCount) => prevCount + 1);
}, 1000);
return () => {
clearInterval(intervalIdRef.current);
};
}, []);
return (
<div>
<h1>{count}</h1>
<button onClick={stopInterval}>Stop Counting</button>
</div>
);
}
This is a common pattern when the callback function needs to persist without
being recreated every render.
function CallbackComponent() {
const [count, setCount] = useState(0);
const callbackRef = useRef(null);
callbackRef.current = () => {
alert("Count is: " + count);
};
useEffect(() => {
const timer = setTimeout(() => {
callbackRef.current();
}, 5000); Alert count value after 5 seconds
return () => clearTimeout(timer);
}, [count]); Re-run effect if count changes
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
The mutable nature of the `ref` object makes it ideal for storing values or
references that persist across renders without causing re-renders.
3. `useMemo`
`useMemo` will return a memoized version of the value/function that only re-
computes if one of the dependencies has changed. This can be useful for
optimization, especially in cases where re-computation is expensive.
Example:
import React, { useState, useMemo } from 'react';
function ExpensiveComputationComponent({ computation, data }) {
const computedValue = useMemo(() => {
Imagine this computation is more expensive
return computation(data);
}, [computation, data]);
return <div>{computedValue}</div>;
}
function App() {
const [number, setNumber] = useState(0);
return (
<div>
<button onClick={() => setNumber(number + 1)}>Increment</button>
<ExpensiveComputationComponent computation={(num) => num 2}
data={number} />
<p>Double: {doubleNumber}</p>
</div>
);
}
Starting with React 16.3, the team introduced new lifecycle methods and also
deprecated some of the old ones to make asynchronous rendering more safe.
Here's a look at the "updating" phase lifecycle methods:
The "updating" phase is triggered every time there's a change in props or state
that might lead to a re-render of the component.
- When it's called: This method is called right before every render, both for the
initial mount and all re-renders.
- Purpose: To allow the component to update its state as the result of changes
in props.
- Usage: It should return an object to update the state, or `null` to update
nothing.
2. `shouldComponentUpdate(nextProps, nextState)`
3. `render()`
- When it's called: This method is required and is called during the updating
and mounting phase.
- Purpose: It examines this.props and this.state and should return one of the
following types: React elements, Arrays and fragments, Portals, String and
numbers, Booleans or null.
4. `getSnapshotBeforeUpdate(prevProps, prevState)`
- When it's called: Right before the most recently rendered output is
committed to the DOM. It enables capturing some information from the DOM
(like scroll position) before it's potentially changed.
- Purpose: Useful when you need to capture some information from the DOM
before it's changed (e.g., the scroll position).
- Usage: Whatever value you return will be passed as the third parameter to
`componentDidUpdate`.
- `componentWillUpdate(nextProps, nextState)`
- `componentWillReceiveProps(nextProps)`
- `UNSAFE_componentWillUpdate(nextProps, nextState)`
- `UNSAFE_componentWillReceiveProps(nextProps)`
Instead of these, you should use the newer lifecycle methods mentioned above
and employ techniques such as the use of the `getDerivedStateFromProps`
method or the Hooks API for function components.
1. Pure Components
Advantages:
- Helps in avoiding unnecessary re-renders.
- Can improve performance in many scenarios.
Example:
Advantages:
- Increases efficiency by only updating changed parts of the real DOM.
- Provides a way to optimize even further with lifecycle methods or hooks.
3. Fragments
Fragments let you return multiple child elements without adding extra nodes
to the DOM.
Advantages:
- No unnecessary wrapping divs.
- More semantic HTML output.
- Can be a performance boost.
Example:
function Columns() {
return (
<Fragment>
<td>Hello</td>
<td>World</td>
</Fragment>
);
}
You can also use the short syntax: `<>` and `</>`
HOCs are functions that take a component and return a new component with
added props or altered behavior.
Advantages:
- Promotes code reusability.
- Can modify props or state before rendering.
- Provides a way to abstract and modularize component behaviors.
Example:
render() {
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}