1、自定义请求Hooks
import React, { useState, useCallback } from "react";const useAsync = (asyncFunction) => { const [data, setData] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const execute = useCallback(() => { setLoading(true); setData(null); setError(null); return asyncFunction() .then((response) => { setData(response); setLoading(false); }) .catch((error) => { setError(error); setLoading(false); }); }, [asyncFunction]); return { execute, loading, data, error };};export default function Test() { const { execute, data, loading, error } = useAsync(async () => { const res = await fetch("https://url"); return res; });}
2、全局Modal对话框
const modalReducer = (state = {}, action) => { const { modalId, status } = action.payload; switch (action.type) { case "modal/handleModalVisible": return { [modalId]: status, }; default: return state; }};function changeModalVisible(modalId, status) { return { type: "modal/handleModalVisible", payload: { modalId, status, }, };}// 创建自定义 Hook 用于处理对话框逻辑export const useNiceModal = ({ dispatch, modalId }) => { const [visible, setVisible] = useState(false); const handleModalVisible = useCallback( (status) => { dispatch(changeModalVisible(modalId, status)).then((res) => { setVisible(res); }); }, [dispatch, modalId] ); return { handleModalVisible, visible };};// 使用function NiceModal({ id, dispatch, children }) { const { handleModalVisible, visible } = useNiceModal({ dispatch, modalId: id, }); return ( <Modal onCancel={() => handleModalVisible(false)} onOk={handleModalVisible(true)} // 默认点击确定关闭对话框 visible={visible} > {children} </Modal> );}
3、使用 Hooks 简化表单处理
const useForm = (initialValues = {}) => { // 设置整个 form 的状态:values const [values, setValues] = useState(initialValues); // 提供一个方法用于设置 form 上的某个字段的值 const setFieldValue = useCallback((name, value) => { setValues((values) => ({ ...values, [name]: value })); }, []); // 返回整个 form 的值以及设置值的方法 return { values, setFieldValue };};// 使用export default () => { const { values, setFieldValue } = useForm(); return ( <input value={values.name || null} onChange={(evt) => setFieldValue("name", evt.target.value)} /> );};
4、定义状态
import { useState, useCallback }from 'react'; function useCounter() { // 定义 count 这个 state 用于保存当前数值 const [count, setCount] = useState(0); //实现加1的操作 const increment = useCallback(() => setCount(count + 1), [count]); //实现减1的操作 const decrement = useCallback(() => setCount(count - 1), [count]); // 重置计数器 const reset = useCallback(() => setCount(0), []); // 将业务逻辑的操作 export 出去供调用者使用 return { count, increment, decrement, reset };}// 使用import React from 'react';function Counter() {// 调用自定义 Hookconst { count, increment, decrement, reset } = useCounter();//渲染UI return ( <div> <button onClick={decrement}> - </button> <p>{count}</p> <button onClick={increment}> + </button> <button onClick={reset}> reset </button> </div> );}
5、监听浏览器状态
import { useState, useEffect } from 'react';// 获取横向,纵向滚动条位置const getPosition = () => { return { x: document.body.scrollLeft, y: document.body.scrollTop, };};const useScroll = () => { // 定一个 position 这个 state 保存滚动条位置 const [position, setPosition] = useState(getPosition()); useEffect(() => { const handler = () => { setPosition(getPosition(document)); }; // 监听 scroll 事件,更新滚动条位置 document.addEventListener("scroll", handler); return () => { // 组件销毁时,取消事件监听 document.removeEventListener("scroll", handler); }; }, []); return position;};import React, { useCallback } from 'react'; import useScroll from './useScroll';function ScrollTop() { const { y } = useScroll(); const goTop = useCallback(() => { document.body.scrollTop = 0; }, []); const style = { position: "fixed", right: "10px", bottom: "10px", }; // 当滚动条位置纵向超过 300 时,显示返回顶部按钮 if(y>300){ return ( <button onClick={goTop} style={style}> Back to Top </button> );}
6、函数组件forceUpdate
export function useForceUpdate() { const [, setState] = useState(0); const update = useCallback(() => { setState((prev) => prev + 1); }, []); return update;}const forceUpdate = useForceUpdate();// 或者const [, forceUpdate] = React.useReducer((x) => x + 1, 0);