7 Aug 2019
- Introduction
- Introduction
- Introduction
- Introduction
Example and comparison
- useState
class Counter extends Component {
state = {
counter: 0
}
increment = this.setState(
({ counter }) => ({ counter: counter + 1 }
)
decrement = this.setState(
({ counter }) => ({ counter: counter - 1 }
)
render() {
return <div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>
}
}
- useState
const Counter = () => {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return <div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>;
}
- useState
const Counter = () => {
const [count, setCount] = useState(0);
const increment = () => setCount(count => count + 1);
const decrement = () => setCount(count => count - 1);
return <div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>;
}
- useState
- useState
- useState
Example and comparison
- useEffect
class Counter extends Component {
state = {
counter: 0
}
componentDidMount() {
document.title = `Ready to count!`;
}
componentDidUpdate(props, state) {
if (this.state.counter !== state.counter) {
document.title = `Counted: ${state.counter}`;
}
}
render() {
return <div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>
}
}
- useEffect
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(
() => document.title = `Counted ${count}`,
[count],
);
useEffect(
() => document.title = `Ready to count`,
[],
);
return <div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>;
}
- useEffect
const NotificationsBadge = ({ id }) => {
const [notifications, setNotifications] = useState(0);
useEffect(
() => {
const subscription = API.subscribeToNotifications(
id,
notification => setNotifications(
notifications => [...notifications, notification]
)
);
return subscription.unsubscribe();
},
[id],
);
return (...);
}
- useEffect
- useEffect
- useEffect
- useEffect
const NotificationsBadge = () => {
const [size, setSize] = useState({ width: 0, height: 0 });
useEffect(
() => {
const handler = () => setSize({
width: window.innerWidth,
height: window.innerHeight,
});
window.addEventListener('resize', handler);
return () => window.removeEventListener('resize', handler);
},
[],
);
return (...);
}
Example
- useMemo
const Counter = () => {
const [count, setCount] = useState(0);
const [hasCounted, setHasCounted] = useState(false);
useEffect(
() => {
if (count !== 0) {
setHasCounted(true);
}
},
[count],
);
const title = useMemo(
() => hasCounted ? `Counted ${count}` : `Ready to count`,
[hasCounted, count],
);
useEffect(
() => document.title = title,
[title],
);
return <div>
<h1>{title}</h1>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>;
}
- useMemo
- useMemo
- useMemo
Example and comparison
- useCallback
- useCallback
const Counter = () => {
const [count, setCount] = useState(0);
const increment = useMemo(
() =>
() => setCount(count => count + 1),
[setCount],
);
const decrement = useCallback(
() => setCount(count => count - 1),
[setCount],
);
return <div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>;
}
- useCallback
const Counter = () => {
const [count, setCount] = useState(0);
const [increment, setIncrement] = useState(null);
// Won't work as expected
useEffect(
() => setIncrement(
() => setCount(count => count + 1)
),
[setCount],
);
const decrement = useCallback(
() => setCount(count => count - 1),
[setCount],
);
return <div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>;
}
Example and comparison
- useContext
const CounterContext =
createContext({ counter, increment, decrement });
class Counter extends Component {
static contextType = CounterContext;
render() {
const { counter, increment, decrement } =
this.context;
return <div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>
}
}
- useContext
- useContext
const CounterContext =
createContext({ counter, increment, decrement });
const Counter = () => (
<CounterContext.Consumer>
{({ counter, increment, decrement }) => (
<div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>
)}
</CounterContext.Consumer>
}
- useContext
const CounterContext =
createContext({ counter, increment, decrement });
const Counter = () => {
const { counter, increment, decrement } = useContext(CounterContext);
return (
<div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>
);
}
- useContext
Example and comparison
- Custom Hooks
Example and comparison
- useReducer
const Counter = () => {
const [count, setCount] = useState(0);
const increment = useCallback(() => setCount(count => count + 1));
const decrement = useCallback(() => setCount(count => count - 1));
return <div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>;
}
- useReducer
const Counter = () => {
const [{ count: counter }, dispatch] = useReducer(
({ count: c }, { type, value }) => {
switch (type) {
case 'increment':
return { count: c + 1 };
case 'decrement':
return { count: c - 1 };
default:
throw new Error('Unknown action');
}
},
{ count: 0 }
);
const increment = useCallback(() => dispatch({ type: 'increment' }), [dispatch]);
const increment = useCallback(() => dispatch({ type: 'decrement' }), [dispatch]);
return <div>
<button onClick={increment}>Increment</button>
<p>Count: {counter}<p>
<button onClick={decrement}>Increment</button>
</div>;
}
- useReducer
- useReducer
- All Done!