React(Rails+react_on_rails)报错:TypeError: _this2.props.people未定义
Hey there, let's walk through why you're hitting this error and how to fix it step by step:
Root Causes of the Error
Looking at your code, here are the key issues leading to the undefined error:
- Incomplete constructor code: Your
Foocomponent's constructor has a truncated linethis.state = { people: this.prop... }— that's a typo (propshould beprops) and incomplete code, sothis.state.peoplenever gets properly initialized. - Missing fallback for props: If your
Foocomponent isn't receiving apeopleprop from its parent (like your Rails view),this.props.peoplewill be undefined, which breaks state initialization. - Unbound
thisindeletePerson: ThedeletePersonmethod isn't bound to the component instance, so when it runs,this.statewill be undefined (leading to more errors once you fix the first issue). - Directly mutating state: You're using
spliceto modify thepeoplearray directly in state — React requires you to update state immutably to trigger re-renders correctly. - Missing
rendermethod inFoo: YourFoocomponent doesn't have arendermethod, so it never renders theCardcomponents, and you can't pass the necessary props down.
Step-by-Step Fixes
1. Fix State Initialization
First, complete the constructor and ensure people is properly initialized. You can either use the global people array you defined, or fall back to it if no people prop is passed:
constructor(props) { super(props); // Use props.people if available, else fall back to your predefined array this.state = { people: props.people || people }; // Bind the deletePerson method to the component instance this.deletePerson = this.deletePerson.bind(this); }
2. Fix the deletePerson Method
Update the method to modify state immutably (don't change the original array — this avoids unexpected bugs in React):
deletePerson(person) { // Create a new array excluding the person to delete const updatedPeople = this.state.people.filter(p => p.id !== person.id); // Update state with the new array this.setState({ people: updatedPeople }); }
Using filter is safer than indexOf because it avoids issues with duplicate objects, and it returns a new array instead of mutating the original.
3. Add the render Method to Foo
Render the Card components by mapping over your state's people array, passing down the required props (including the onClick handler):
render() { return ( <div className="people-cards"> {this.state.people.map(person => ( <Card key={person.id} name={person.name} avatar={person.avatar} onClick={() => this.deletePerson(person)} /> ))} </div> ); }
Note: Always add a unique key prop when mapping over arrays in React — this helps React track component changes efficiently.
4. Ensure Props Are Passed (Rails Integration)
If you're passing people from your Rails view to the Foo component via react_on_rails, make sure you're passing the data correctly. For example, in your Rails template:
<%= react_component("Foo", { people: @people }) %>
Where @people is the Rails data you want to pass to React (serialized as JSON).
Full Corrected Code
Here's the complete fixed code:
import React from 'react'; // Predefined people array (fallback if no props are passed) const people = [ { "name": "Sister Altenwerth", "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/ryandownie/128.jpg", "id": 3 } ]; class Card extends React.Component { render() { return ( <div className="card"> <h2>{this.props.name}</h2> <img src={this.props.avatar} alt={`${this.props.name}'s avatar`} /> <button onClick={this.props.onClick}>Delete Me</button> </div> ); } } class Foo extends React.Component { constructor(props) { super(props); this.state = { people: props.people || people }; this.deletePerson = this.deletePerson.bind(this); } deletePerson(person) { const updatedPeople = this.state.people.filter(p => p.id !== person.id); this.setState({ people: updatedPeople }); } render() { return ( <div className="people-container"> {this.state.people.map(person => ( <Card key={person.id} name={person.name} avatar={person.avatar} onClick={() => this.deletePerson(person)} /> ))} </div> ); } } export default Foo;
These changes should resolve the _this2.props.people is undefined error, fix the state mutation issue, and get your delete functionality working correctly.
内容的提问来源于stack exchange,提问作者Trinity76




