React中setState用法及失效排查:赋值后为何输出空字符串
Hey there, let's break down why you're seeing an empty string in the console even after calling setData, and fix it step by step:
1. The Core Problem: Async State Updates & Timing
First off, React's useState updates are asynchronous. When you call setData('new data') inside your getDatas function, React doesn't update the data state immediately—it queues the update for the next render cycle.
On top of that, your console.log(data) runs right after calling getDatas() in the initial useEffect. Since getDatas is an async function, the log executes before the async request finishes and setData is even called. That's why you're stuck seeing the initial empty string.
2. Secondary Issue: Variable Name Collision
You've got a subtle variable name clash in your getDatas function:
const { data } = await http().get('todo');
This data variable (from the API response) shadows the component-level data state variable. While it doesn't break your current setData call, it's confusing and could lead to bugs later if you accidentally use the wrong data.
Fixed Code & Explanations
Here's the adjusted code with fixes for both issues:
const App = (params) => { const [data, setData] = useState(''); const getDatas = async () => { // Rename the API response data to avoid collision with state const { data: responseData } = await http().get('todo'); setData('new data'); // Optional: Log the value you're setting if you want immediate confirmation console.log('Value queued for state update:', 'new data'); }; // Run once on mount to fetch data useEffect(() => { getDatas(); }, []); // Separate useEffect to log whenever data state changes useEffect(() => { console.log('Updated data state:', data); }, [data]); // Depend on data so this runs every time state updates return ( <div className="border">Display text</div> ); };
Key Changes:
- Renamed API response variable:
responseDatainstead ofdataeliminates the shadowing issue, making your code easier to read and debug. - Split useEffect logic: The first
useEffecthandles the initial data fetch on mount. The seconduseEffectlistens specifically for changes to thedatastate, ensuring you log the latest value as soon as React finishes updating the state. - Clearer state tracking: By relying on the
datadependency in the second useEffect, you're guaranteed to log only after the state has actually updated.
Why This Works
React batches state updates to optimize performance, so state changes don't take effect mid-render. The dedicated useEffect for logging ensures you're accessing the most up-to-date state value every time it changes.
内容的提问来源于stack exchange,提问作者schutte

