You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React(Rails+react_on_rails)报错:TypeError: _this2.props.people未定义

Fixing "TypeError: _this2.props.people is undefined" in React on Rails

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 Foo component's constructor has a truncated line this.state = { people: this.prop... } — that's a typo (prop should be props) and incomplete code, so this.state.people never gets properly initialized.
  • Missing fallback for props: If your Foo component isn't receiving a people prop from its parent (like your Rails view), this.props.people will be undefined, which breaks state initialization.
  • Unbound this in deletePerson: The deletePerson method isn't bound to the component instance, so when it runs, this.state will be undefined (leading to more errors once you fix the first issue).
  • Directly mutating state: You're using splice to modify the people array directly in state — React requires you to update state immutably to trigger re-renders correctly.
  • Missing render method in Foo: Your Foo component doesn't have a render method, so it never renders the Card components, 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

火山引擎 最新活动