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 »

React-quiz-app

React Quiz App 🧠 This project highlights hands‑on understanding of React fundamentals, component‑based architecture, and efficient state management. Live demo...

Redux Explained in Depth

Introduction State management is one of the hardest problems in front‑end development. As applications grow, keeping data consistent across components becomes...