useReducer vs useState

Published: (February 5, 2026 at 02:23 PM EST)
2 min read
Source: 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

When using the useState hook, you define a separate setter function (e.g., setContactName) for each piece of state you want to manage.

With useReducer, a single dispatch function is shared among all state updates. The dispatch sends an action to the reducer function, which determines how to update the state based on the action type.

const [state, dispatch] = useReducer(reducer, initialState);
  • state – an object containing all tracked values.
  • dispatch – a function that sends actions to the reducer.
  • reducer – a pure function that receives the current state and an action, returning the new state.
  • initialState – the initial values for the state object.
Back to Blog

Related posts

Read more »

Understanding `useState` in React

What Problem Does useState Solve? Before React, updating something on the screen required: - Finding the HTML element - Manually updating it - Making sure noth...

ReactJS Hook Pattern ~Deriving State~

!Cover image for ReactJS Hook Pattern ~Deriving State~https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2...

React Function and Class Components

Function Components In React, function components are defined as simple JavaScript functions that receive props properties from parent components as arguments...