About Hooks
useState
useEffect
useRef
useMemo
useCallback
Custom Hook
useContext
useReducer
F&Q
讓 Function Component 能用更簡單直覺的方式
使用 React 的功能
狀態邏輯難以共享
複雜組件難以維護
Class 難以理解
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}import React, { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}const [count, setCount] = useState(0)function ExampleWithManyStates() {
const [count, setCount] = useState(0);
const [title, setTitle] = useState('標題');
const [todos, setTodos] = useState([{ text: '我是文字' }]);
// class component
this.state = {name: "Hank", age: 18}
this.setState({age: 30})
console.log(this.state) // {name: "Hank", age: 30}
// hooks example 1
const [user, setUser] = useState({name: "Hank", age:18})
setUser({age: 30})
console.log(user) // {age: 30}
// hooks example 2
const [user, setUser] = useState({name: "Hank", age:18})
setUser({...user, age: 30})
console.log(user) // {name: "Hank", age: 30}
// hooks example 3
const [user, setUser] = useState({name: "Hank", age:18})
setUser((prevUser) => {...prevUser, age: 30})
console.log(user) // {name: "Hank", age: 30}useState 更新狀態時,不會自動合併物件
每次 setState 的時候給予的值,都會變成全新的狀態
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate(prevProps, prevState) {
if( prevState.count !== this.state.count ) {
document.title = `You clicked ${this.state.count} times`;
}
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}useEffect(() => {
document.title = `You clicked ${count} times`;
});class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
windowWidth: window.innerWidth
};
}
resizeHandler = () => {
this.setState({ windowWidth: window.innerWidth });
};
componentDidMount() {
window.addEventListener("resize", this.resizeHandler);
}
componentWillUnmount() {
window.removeEventListener("resize", this.resizeHandler);
}
render() {
return (
<div>
<p>windowWidth: {this.state.windowWidth}</p>
</div>
);
}
}import React, { useState, useEffect } from 'react';
function Example() {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
const resizeHandler = () => {
setWindowWidth(window.innerWidth)
}
useEffect(() => {
window.addEventListener("resize", resizeHandler);
return () => {
window.removeEventListener("resize", resizeHandler);
}
}, []);
return (
<div>
<p>windowWidth: {windowWidth}</p>
</div>
);
}useEffect(() => {
window.addEventListener("resize", resizeHandler);
return () => {
// 清理函式
window.removeEventListener("resize", resizeHandler);
}
}, []);import React, { useRef } from 'react';
function Example() {
const inputEl = useRef(null);
const clickHandler = () => {
inputEl.current.focus();
}
return (
<div>
<input ref={inputEl} type="text" />
<button onClick={clickHandler}>Click me</button>
</div>
);
}import React, { useRef } from "react";
function Example() {
const countRef = useRef(0);
return (
<div>
<p>You clicked {countRef.current} times</p>
<button
onClick={() => {
countRef.current += 1;
}}
>
Click me
</button>
<button
onClick={() => {
alert(countRef.current);
}}
>
Alert
</button>
</div>
);
}
import React, { useState, useMemo } from 'react';
function Example() {
const [count, setCount] = useState(0);
const square = useMemo(() => {
return count * count;
}, [count])
return (
<div>
<p>You clicked {count} times</p>
<p>{count} * {count} = {square}</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}import React, { useState, useCallback } from 'react';
function Example() {
const [count, setCount] = useState(0);
const clickHandler = useCallback(() => {
setCount(count + 1)
}, [count])
return (
<div>
<p>You clicked {count} times</p>
<button onClick={clickHandler}>
Click me
</button>
</div>
);
}1. 確保 Hooks 執行順序 (重要)
2. Hooks 只能用在兩個地方, function component 或 custom hook
3. 不用急著把所有組件都改寫成 Hooks, 除非你本來就想要重寫
所有物質都是由原子組成的,當科學家發現原子時,取名叫做 atom(意指不可分割),但後來又在原子裡發現電子的存在,電子的特性甚至更能解釋原子之間的交互作用。
Hooks 之於 Components 就好比電子之於原子, Hooks 並不是新的東西,但它更能表現 Components 之間的運作關係,React 的 Logo 看起來就像是電子繞著原子,其實 Hooks 一直都在,只是我們沒有發現而已
Dan Abramov
React Logo
有問題可以提出喔