React:在Ajax回调中设置组件状态遇问题求助
Hey there! No worries—these are super common pitfalls when starting out with React and JavaScript callbacks, so you’re definitely not alone here. Let’s break down what’s going wrong and how to fix it step by step.
1. The 'this' Context Problem in Your Callback
When you pass the anonymous function to getIncomes in componentDidMount, the this inside that function doesn’t refer to your ExpensesGrid component. That means this.setState is undefined here, so your state never gets updated with the AJAX data you’re fetching.
Easy Fixes for This:
- Use an arrow function: Arrow functions inherit the context from where they’re defined, so
thiswill correctly point to your component:componentDidMount() { getIncomes((i) => { this.setState({ incomes: i }); }); } - Or bind the function: If you prefer regular functions, you can explicitly bind
thisto the component:componentDidMount() { getIncomes(function(i) { this.setState({ incomes: i }); }.bind(this)); }
2. Initial State Mismatch
You initialized incomes as an empty object ({}), but you’re trying to call map on it—and objects don’t have a map method. If your API returns an array of income entries, you should start with an empty array instead:
constructor(){ super(); this.state= { incomes: [], // Changed from {} to [] expenses:{}, savings:{} }; }
This way, even before the AJAX call finishes, this.state.incomes.map will run on an empty array (safe, no errors) instead of trying to map over an object.
3. Verify the AJAX Response
Double-check that the data coming back from /get_incomes/January is actually an array. You can log it to confirm:
getIncomes((i) => { console.log("Incoming data:", i); // See what the API returns this.setState({ incomes: i }); });
If the response is wrapped in an object (like { data: [...] }), you’ll need to access the array inside it, e.g., this.setState({ incomes: i.data }).
Corrected Component Code
Here’s your full fixed component:
class ExpensesGrid extends React.Component { constructor(){ super(); this.state= { incomes: [], expenses:{}, savings:{} }; } componentDidMount() { getIncomes((i) => { this.setState({ incomes: i }); }); } render() { return ( <div className="expenses_grid"> <table> <tr><th>Incomes</th><th>Default Value</th><th>Actual Value</th></tr> {this.state.incomes.map(row => <ExpensesGridrows row={row}/>)} </table> </div> ) } }
This should resolve the "Cannot read property 'map' of undefined" error and correctly update your state with the fetched data.
内容的提问来源于stack exchange,提问作者Jonny B

