useReducer 与 useState

发布: (2026年2月6日 GMT+8 03:23)
2 min read
原文: Dev.to

Source: Dev.to

useState

const [contactName, setContactName] = useState("");
const [contactImage, setContactImage] = useState(null);
const [contactImageUrl, setContactImageUrl] = useState(null);

function handleImageUpload(e) {
    const file = e.target.files[0];
    const fileName = e.targe.files[0].name;

    if (!file) return;

    const matchRgx = fileName.match(/\.(jpg|png|jpeg)/);
    if (matchRgx != null) {
        setContactImageUrl(URL.createObjectURL(e.target.files[0]));
    } else {
        setContactImage(null);
        setContactImageUrl(null);
    }
}

function handleForm(e) {
    e.preventDefault();
    window.alert("Successfully added a contact!");
}

return (
    
        
            Name:
             setContactName(e.target.value)}
            />

            Image:
            

            

            Submit
        
    
);

useReducer

const initialFormState = { contactName: "", contactImage: null, contactImageUrl: null };

function reducer(state, action) {
    if (action.type === "setState") {
        return {
            ...state,
            [action.field]: action.value,
        };
    } else if (action.type === "ImageUpload") {
        return {
            ...state,
            contactImage: action.file,
            contactImageUrl: action.url,
        };
    }
    return state;
}

const ReducerHook = () => {
    const [state, dispatch] = useReducer(reducer, initialFormState);

    function handleImageUpload(e) {
        const file = e.target.files[0];
        const fileName = e.targe.files[0].name;

        if (!file) return;

        const matchRgx = fileName.match(/\.(jpg|png|jpeg)/);
        if (matchRgx != null) {
            const imageUrl = URL.createObjectURL(e.target.files[0]);
            dispatch({
                type: "ImageUpload",
                file: e.target.files[0],
                url: imageUrl,
            });
        } else {
            dispatch({
                type: "ImageUpload",
                file: null,
                url: null,
            });
        }
    }

    function handleName(e) {
        e.preventDefault();
    }

    return (
        
            
                Name:
                 {
                        dispatch({
                            type: "setState",
                            field: e.target.name,
                            value: e.target.value,
                        });
                    }}
                />

                Image:
                
                

                Submit
            
        
    );
};

export default ReducerHook;

Explanation

当使用 useState Hook 时,你需要为每个想要管理的状态单独定义一个 setter 函数(例如 setContactName)。

使用 useReducer 时,所有状态更新共用同一个 dispatch 函数。dispatch 会向 reducer 函数发送一个 action,reducer 根据 action 的类型决定如何更新状态。

const [state, dispatch] = useReducer(reducer, initialState);
  • state – 包含所有被跟踪值的对象。
  • dispatch – 用于向 reducer 发送 action 的函数。
  • reducer – 一个纯函数,接收当前状态和一个 action,返回新的状态。
  • initialState – 状态对象的初始值。
Back to Blog

相关文章

阅读更多 »

理解 React 中的 useState

useState 解决了什么问题?在 React 之前,更新屏幕上的内容需要: - 找到 HTML 元素 - 手动更新它 - 确保不…

ReactJS Hook 模式 ~派生状态~

ReactJS Hook 模式 ~Deriving State~ 的封面图片 https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2...

React 函数组件和类组件

函数组件 在 React 中,函数组件被定义为简单的 JavaScript 函数,它们从父组件接收 props 属性作为参数……