开发者问题收集

在 React 应用中获取“未捕获的类型错误”

2018-11-21
1116

我是 React 新手,为了练习,我尝试在我的 Twitter 类应用上创建一个“删除按钮”。它看起来应该和真正的 Twitter 一样,有一个我所有推文的列表,每条推文都有一个删除按钮。 我成功显示了我的所有推文,但目前我的删除按钮出现错误,提示 Uncaught TypeError: this.props.onDelete is not a function ,我不知道如何修复它。我怎样才能让它工作?

我的代码如下:

Tweet.js

import React from 'react'

class Tweet extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tweet: this.props.tweet,
      id: this.props.id,
    };
    this.handleDelete = this.handleDelete.bind(this);
  }
  handleDelete(id) {
    this.props.onDelete(id);
  }
  render() {
    const tweet = this.state.tweet;
    return (
      <div>
        <p>{tweet.user.user_name} {tweet.created_at}</p>
        <p>{tweet.tweet}</p>
        <button onClick={this.handleDelete(tweet.id)}>DELETE</button>
      </div>
    );
  }
}

export default Tweet;

Tweets.js

import React from 'react'
import Tweet from './Tweet'

class Tweets extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tweet: this.props.tweet,
      id: this.props.id,
    };
  }
  render() {
    const tweets = this.props.tweets.map(function (tweet) {
      return <Tweet tweet={tweet} key={tweet.id} />;
    });
    return (
      <div>
        {tweets}
      </div>
    );
  }
}

export default Tweets;

TweetsPage.js

import React from 'react'
import Tweets from './Tweets'

class TweetsPage extends React.Component {
  constructor() {
    super();
    this.state = {
      tweets: [],
      id: '',
    };
    this.onSubmitDelete = this.onSubmitDelete.bind(this);
  }
  loadTweetsFromServer() {
    const url = '/tweets/index.json';
    $.ajax({
      url: url,
      dataType: 'json',
      type: 'GET',
      cache: false,
      success: (data) => {
        this.setState({
          tweets: data
        });
      },
      error: (xhr, status, err) => {
        console.error(url, status, err.toString());
      },
    });
  }
  onSubmitDelete(id) {
    const url = '/tweets/destroy';
    $.ajax({
      url: url,
      type: 'POST',
      cache: false,
      data: {
        id: id
      },
      success: (data) => {
        this.loadTweetsFromServer();
      },
      error: (xhr, status, err) => {
        console.error(url, status, err.toString());
      },
    });
  }
  componentDidMount() {
    this.loadTweetsFromServer();
  }
  render() {
    return (
      <div>
        <Tweets tweets={this.state.tweets} onDelete={this.onSubmitDelete} />
      </div>
    );
  }
}

export default TweetsPage;
2个回答

您将 onDelete 函数作为 prop 传递给您的 Tweets 组件,但没有传递给您的 Tweet 组件。您的 Tweet 组件尝试在 handleDelete 函数中调用它。要解决此问题,请将 prop 传递给 Tweet 组件。

render() {
    let that = this
    const tweets = this.props.tweets.map(function (tweet) {
      return <Tweet tweet={tweet} key={tweet.id}  onDelete={that.props.onDelete} />;
    });
    return (
      <div>
        {tweets}
      </div>
    );
  }
Leo Farmer
2018-11-21

您需要将处理程序传递给子级。其余代码均完美无缺。

TweetsPage.js - 此文件中无任何更改

import React from 'react'
import Tweets from './Tweets'

class TweetsPage extends React.Component {
  constructor() {
    super();
    this.state = {
      tweets: [],
      id: '',
    };
    this.onSubmitDelete = this.onSubmitDelete.bind(this);
  }
  loadTweetsFromServer() {
    // load and set state
  }
  onSubmitDelete(id) {
    // submit delete req to server
  }
  componentDidMount() {
    this.loadTweetsFromServer();
  }
  render() {
    return (
      <div>
        <Tweets tweets={this.state.tweets} onDelete={this.onSubmitDelete} />
      </div>
    );
  }
}

export default TweetsPage;

Tweets.js - 注意更改

import React from 'react'
import Tweet from './Tweet'

class Tweets extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tweet: this.props.tweet,
      id: this.props.id,
    };
  }
  render() {
    let { onDelete, tweets } = this.props; // note this line
    // note the next line - arrow function and different variable name
    const renderedTweets = tweets.map((tweet) => {
      // note the next line
      return <Tweet tweet={tweet} key={tweet.id} onDelete={onDelete} />; 
    });
    return (
      <div>
        {renderedTweets}
      </div>
    );
  }
}

export default Tweets;

Tweet.js - 此文件中无任何更改

import React from 'react'

class Tweet extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tweet: this.props.tweet,
      id: this.props.id,
    };
    this.handleDelete = this.handleDelete.bind(this);
  }
  handleDelete(id) {
    this.props.onDelete(id);
  }
  render() {
    const tweet = this.state.tweet;
    return (
      <div>
        <p>{tweet.user.user_name} {tweet.created_at}</p>
        <p>{tweet.tweet}</p>
        <button onClick={this.handleDelete(tweet.id)}>DELETE</button>
      </div>
    );
  }
}

export default Tweet;
Dinesh Pandiyan
2018-11-21