Professional Documents
Culture Documents
3|Page 4|Page
• Class way
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) { class FriendStatus extends React.Component {
case 'increment': state = { isOnline : null };
componentDidMount() {
return {count: state.count + 1};
ChatAPI.subscribeToFriendStatus(
case 'decrement':
this.props.friend.id,
return {count: state.count - 1};
this.handleStatusChange
default: );
throw new Error(); }
} componentWillUnmount() {
} ChatAPI.unsubscribeFromFriendStatus(
function Counter({initialState}) { this.props.friend.id,
const [state, dispatch] = useReducer(reducer, initialState); this.handleStatusChange
return ( );
<> }
Count: {state.count} componentDidUpdate(prevProps) {
<button onClick = {() => dispatch({type: 'increment'})}>+</button> if(this.props.friend.id !== prevProps.id) {
ChatAPI.unsubscribeFromFriendStatus(
<button onClick = {() => dispatch({type: 'decrement'})}>+</button>
prevProps.friend.id,
</>
this.handleStatusChange
);
);
} ChatAPI.subscribeToFriendStatus(
this.props.friend.id,
this.handleStatusChange
);
HANDLE SIDE EFFECTS }
}
5|Page 6|Page
• Hook Way useLayoutEffect is almost same as useEffect, but fires
synchronously after the render phase. Use this to safely read from
import { useState, useEffect } from 'react';
function FriendStatus(props) { or write to the DOM
const [isOnline, setIsOnline] = useState(null);
status
import { useRef, useLayoutEffect } from "react";
const handleStatusChange = (status) => setIsOnline(status.isOnline);
useEffect( function ColoredComponent({color}) {
const ref = useRef();
() => {
// Update status when the listener triggers useLayoutEffect(() => {
ChatAPI.subscribeToFriendStatus( const refColor = ref.current.style.color;
props.friend.id, console.log(`${refColor} will always be the same as ${color}`);
handleStatusChange ref.current.style.color = "rgba(255,0,0)";
}, [color]);
);
// Stop listening to status changes every time we cleanup useEffect(() => {
return function cleanup() { const refColor = ref.current.style.color;
console.log(
ChatAPI.unsubscribeFromFriendStatus(
`but ${refColor} can be different from ${color} if you play with the
props.friend.id,
handleStatusChange DOM`
); );
}; }, [color]);
}, return (
[props.friend.id] // Cleanup when friend id changes or when we "unmount" <div ref={ref} style={{ color: color }}>
); Hello React hooks !
if (isOnline === null) { </div>
return 'Loading...'; );
}
}
return isOnline ? 'Online' : 'Offline';
}
<ColoredComponent color = {"rgb(42, 13, 37)"}/>
// rgb(42, 13, 37) will always be the same as rgb(42, 13, 37)
// but rgb(255, 0, 0) can be different from rgb(42, 13, 37) if you play with the DOM
useLayoutEffect
useLayoutEffect(() => {
applyBlockingEffect(dependencies);
return cleanupEffect();
}, [dependencies]);
7|Page 8|Page
USE THE CONTEXT API • Hook Way
9|Page 10 | P a g e
function RandomColoredLetter(props) { USE REFS
const [color, setColor] = useState('#fff')
const [letter, setLetter] = useState('a')
useRef
const handleColorChange = useMemo(() => () =>
setColor(randomColor()), []);
const handleLetterChange = useMemo(() => () => const ref = useRef();
setLetter(randomColor()), []);
return (
<div> useRef can just be used as a common React ref :
<ColorPicker handleChange={handleColorChange} color={color} />
<LetterPicker handleChange={handleLetterChange} letter={letter} /> import { useRef } from "react";
<hr/> function TextInput() {
<h1 style={{color}}>{letter}</h1> const inputRef = useRef(null);
</div> const onBtnClick = () => inputRef.current.focus();
) return (
} <>
<input ref={ref} />
<button onClick={onBtnClick}>Focus the text input</button>
useCallback </>
)
}
const memoizedCallback = useCallback (
expensiveFn (dependencies),
[dependencies] But it also allows you to just hold a mutable value through any
);
render. Also, mutating the value of ref.current will not cause any
11 | P a g e 12 | P a g e
useImperativeHandle allows you to customize the exposed interface
REUSABILITY
of a component when using a ref. The following component will
automatically focus the child input when mounted : Extract reusable behaviour into custom hooks.
13 | P a g e 14 | P a g e