-2

I'm trying to use This inside a function on a arrow function. How can I use setState inside my function?

showDeleteConfirm = commentId => {
    const { deleteComment } = this.props;
    const { comments } = this.state;
    // this exist
    confirm({
      title: 'Are you sure delete this?',
      okText: 'Yes',
      okType: 'danger',
      cancelText: 'No',
      onOk() {
        // this is undefined
        deleteComment(commentId);
        const targetPosition = _.findIndex(comments, item => {
          return item._id === commentId;
        });
        if (targetPosition !== -1) {
          // this is undefined
          console.log(this.state.comments);
          this.setState(prevState => ({
            comments: [
              ...prevState.comments.slice(0, targetPosition),
              ...prevState.comments.slice(targetPosition + 1)
            ]
          }));
        }
      },
      onCancel() {
        console.log('Cancel');
      }
    });
  };
iceveda06
  • 601
  • 8
  • 21
Juan P. Ortiz
  • 568
  • 1
  • 6
  • 21

2 Answers2

1

You can't, the this in an arrow function is always the same as the this in its surrounding block. Just use a regular function instead.

const showDeleteConfirm = function(commentId) {
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

You get the this in an arrow function just fine (method = () => {}), although using a method inside a class is encouraged (method() {}). The problem you are facing is not due using an arrow function but where and how you call it. The first part of the code works because you are calling it immediately. Whereas onOK and onCancel are at a later time and more importantly outside the context of showDeleteConfirm, where ever onOK is defined. Surely onOK will execute with its own this, not showDeleteConfirm's this. Here is a way to solve it:

showDeleteConfirm = commentId => {
    const { deleteComment } = this.props;
    const { comments } = this.state;

    confirm({
        title: 'Are you sure delete this?',
        okText: 'Yes',
        okType: 'danger',
        cancelText: 'No',
        onOk: this.onDeleteConfirm.bind(this, commentId),
        onCancel: this.onDeleteCancel.bind(this)
    });
};

onDeleteConfirm = (commentId) => {
    const { comments } = this.state;
    const targetPosition = comments.findIndex(item => item._id === commentId);

    this.props.deleteComment(commentId);

    if (targetPosition !== -1) {
        this.setState(prevState => ({
            comments: [
                ...prevState.comments.slice(0, targetPosition),
                ...prevState.comments.slice(targetPosition + 1)
            ]
        }));
    }
}

onDeleteCancel = () => {}

We bind the this toonDeleteConfirm andonDeleteCancel, so when they are eventually executed they get their this properly.You can read abound bind here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind

Vijay Dev
  • 1,024
  • 7
  • 14