React Hooks 是 16.7 版推出的功能,使用 React Hooks 讓我們可以減少使用 Class Components 去建構我們的 React 應用程式。
使用 useState 可以讓我們的 Functional Components 具備狀態,userState 的 setter 比 setState 更具可讀性。
function App() {
const [count, setCount] = useState(0);
const incrementCount = () => setCount(prevCount => prevCount + 1);
return (
<button onClick={incrementCount}>{count}</button>
);
}
用來處理副作用(可以理解為一切除結果計算之外發生的事情,ex:發送一個http 請求)
function App() {
const [mousePosition, setMousePosition] = useState({ x: null, y: null });
useEffect(() => {
document.title = 'hi title';
}, []);
useEffect(() => {
window.addEventListener('mousemove', handleMouseMove);
return () => {
window.removeEventListener('mousemove', handleMouseMove);
}
}, []);
const = handleMouseMove = (event) => {
setMousePosition({ x: pageX, y: pageY });
};
...
}
function App() {
const [onLine, setOnLine] = useState(navigator.onLine);
useState(() => {
window.addEventListener('online', handleOnLine);
window.addEventListener('offline', handleOffLine);
return () => {
window.removeEventListener('online', handleOnLine);
window.removeEventListener('offline', handleOffLine);
};
}, []);
const handleOnLine = () => {
setOnLine(true);
};
const handleOffLine = () => {
setOnLine(false);
};
}
const initialLocationState = {
latitude: null,
langitude: null,
speed: null,
};
function App() {
const [location, setLocation] = useState(initialLocationState);
let mounted = true;
useEffect(() => {
navigator.geolocation.getCurrentPosition(handleGeolocation);
const watchId = navigator.geolocation.watchPosition(handleGeolocation);
return () => {
mounted = false;
navigator.geolocation.clearWatch(watchId);
}
}, []);
const handleGeolocation = (event) => {
if (mounted) {
setLocation({
latitude: event.coords.latitude,
langitude: event.coords.langitude,
speed: event.coords.speed,
});
}
};
}
function App() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
const userData = {
username,
password,
};
// do something
setUsername('');
setPassword('');
};
return (
<form onSubmit={handleSubmit}>
<input
placeholder="Username"
value={username}
onchange={(event) => setUsername(event.target.value)}
/>
<input
placeholder="Password"
value={password}
onchange={(event) => setPassword(event.target.value)}
/>
<button type="submit">Login</button>
</form>
);
}
const initialFormState = {
username: '',
email: '',
password: '',
};
function App() {
const [form, setForm] = usestate(initialFormState);
const handleChange = (event) => {
setForm({
...form,
[event.target.name]: event.target.value,
});
};
const handleSubmit = (event) => {
event.preventDefault();
...
setForm(initialFormState);
};
...
}
function App() {
const [query, setQuery] = useState('');
const [user, setUser] = useState(null);
const [err,] = useState(null);
useEffect(() => {
fetchUser(query);
}, [query])
const fetchUser = async (query) => {
try {
const response = await axios.get('endpoint', { params: query });
setUser(response.data);
}
catch(err) {
setErr(err);
}
};
}
const UserContext = React.createContext();
function App() {
const value = useContext(UserContext);
return (
<div>Hi, {value}</div>
);
}
ReactDOM.render(
<UserContext.Provider value={'william'}>
<App/>
</UserContext.Provider>,
document.getElementById('root')
);
// context.js
export default React.createContext({
todos: [
{ id: 1, text: 'eat breakfast', complete: false },
{ id: 2, text: 'reading', complete: false },
{ id: 3, text: 'sleep', complete: false },
],
currentTodo: {}
});
// reducer.js
export default reducer(state, action) {
switch(action.type) {
case 'TOGGLE_TODO':
return {
...state,
todos: state.todos.map(todo =>
todo.id === action.payload.id
? { ...todo, complete: !todo.complete }
: todo
};
case 'REMOVE_TODO':
return {
...state,
todos: state.todos.filter(todo => todo.id === action.payload.id)
};
default:
return state;
}
}
// index.js
import Context from './context';
import reducer from './reducer';
const App = () => {
const initialState = useContext(context);
const [state, dispatch] = useReducer(initialState, reducer);
return (
<Context.Provider value={{ state, dispatch }}>
<TodoList />
</Context.Provider>
);
}