在React应用中获取“未捕获的TypeError”

时间:2018-11-21 01:50:42

标签: javascript reactjs

我是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 个答案:

答案 0 :(得分:3)

您将onDelete函数作为道具传递给Tweets组件,而不传递给Tweet组件。您的Tweet组件尝试在handleDelete函数中调用它。要解决此问题,请将道具传递到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>
    );
  }

答案 1 :(得分:1)

您需要将处理程序传递给您的孩子。您其余的代码是完美的。

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;