为何Redux dispatch会在React Hook状态更新前执行?
dispatch Runs Before values Updates in Your React Component Hey Nora, I totally get why this is confusing—let’s break down what’s happening here and fix it up.
The Root Cause: setValues Is Asynchronous
React’s useState updates are asynchronous and batched for performance. When you call setValues, React doesn’t immediately update the values variable in your component’s closure. Instead, it queues the update and re-renders the component later with the new state.
In your code, right after calling setValues, you’re dispatching with the original values variable:
setValues({ ...values, [field_name]: event.target.value }); props.dispatch({ type: 'PLEASE_WORK', payload: values }); // Still uses the OLD `values`!
At this point, values hasn’t been updated yet—it’s still the version from before the setValues call. That’s why your dispatch is sending stale data.
Fix 1: Dispatch the New State Directly
Since you’re already constructing the new state object when calling setValues, you can reuse that same object for your dispatch. This way, you don’t have to wait for React to update the values variable:
const handleInputFieldChange = field_name => event => { const inputValue = event.target.value; // Create the updated state object first const updatedValues = { ...values, [field_name]: inputValue }; setValues(updatedValues); // Dispatch the same updated object props.dispatch({ type: 'PLEASE_WORK', payload: updatedValues }); };
This ensures both your local state and Redux store get the latest value immediately, no async waiting needed.
Fix 2: Use useEffect to Trigger Dispatch on State Change
If you want to dispatch every time values updates (not just when a field changes), you can use a useEffect hook that listens for changes to values:
import React, { useState, useEffect } from 'react'; // ... inside your component ... useEffect(() => { // This runs AFTER `values` has been updated and the component re-renders props.dispatch({ type: 'PLEASE_WORK', payload: values }); }, [values, props.dispatch]); // Re-run when `values` or `dispatch` changes const handleInputFieldChange = field_name => event => { setValues({ ...values, [field_name]: event.target.value }); };
This is great if you have multiple fields updating and want to sync the entire values object to Redux whenever any part of it changes.
Quick Note About That console.log
You might have noticed your console.log('Project values', values) shows the updated value after typing—this is because the console.log runs during the component re-render, which happens after React has processed the state update. The dispatch, however, runs immediately after setValues, before the re-render, so it uses the old values from the current closure.
内容的提问来源于stack exchange,提问作者Nora

