为什么在React中需要两次绑定onClick?

时间:2019-01-23 11:20:21

标签: javascript reactjs

我有一个LandingPageComponent,其中有一个子组件DisplayStudent

我在deleteStudent中有一个函数LandingPageComponent。我正在将此功能作为对DisplayStudent的支持,但我不明白为什么我需要在function deleteStudentLandingPageComponent中绑定DisplayStudent

点击删除按钮时,我需要获取id,请在jsFiddle上查看

jsfiddle

import React, {
  Component
} from 'react';
import DisplayStudent from './DisplayEmployeeComponent'

var data = [{
    name: 'student-1',
    id: 1
  },
  {
    name: 'student-2',
    id: 2
  },
  {
    name: 'student-3',
    id: 3
  }
];

export default class LandingPage extends Component {
  deleteStudent(e) {
    console.log('hi', this, e)
  }

  render() {
    return ( <
      div >
      <
      DisplayStudent studentData = {
        data
      }
      deleteStudent = {
        this.deleteStudent.bind(this)
      } // BINDING FIRST TIME
      /> < /
      div >
    )
  }
}

export default function(props) {
  return (
    props.studentData.map((ele) => {
      return ( <
        div key = {
          ele.id
        }
        style = {
          {
            display: 'flex',
            padding: '9px 5px 7px 4px'
          }
        } >
        <
        div > {
          ele.name
        } < /div>

        <
        button onClick = {
          props.deleteStudent.bind(this, ele.id)
        } // binding second time
        >
        Delete <
        /button> < /
        div >
      )
    })
  )
}

5 个答案:

答案 0 :(得分:3)

在没有.bind(this)的情况下,this内的deleteStudent指向全局对象(window),而不是组件。

详细了解bindthis

答案 1 :(得分:1)

您应该bind一次。如果两次,则第二次不适用。 最佳做法是紧接着constructorsuper上实现它 有关更多信息,请阅读Arrow functions

答案 2 :(得分:1)

您可以避免在ES6中先绑定甚至再绑定。这是工作示例:https://jsfiddle.net/bayucandra/xch1L072/9/

说明:




第一次绑定

  deleteStudent = (e) => {
    console.log('hi', this, e)
  };

这是我们在Babel中为{6}做ES6的一种新方法。只是语法糖就老了。旧方法是在构造函数中执行bind(this)




第二次绑定

bind(this)

您需要那些 <button onClick={props.deleteStudent.bind(this, ele.id)} > Delete </button> ,因为您需要从bind()传递ele.id作为e的自变量

如果您不想通过这种方式,则可以使用ES6的粗箭头,如下所示:

props.deleteStudent(e)

通过这种方式,您将绑定在其内部调用 <button onClick={() => props.deleteStudent(ele.id)} > Delete alternative </button> 的函数。

答案 3 :(得分:0)

不是必需的。 props.deleteStudent.bind(this, ele.id)具有误导性,因为this在功能组件内部不可用(它是全局的或undefined),但不会影响deleteStudent,因为它已经绑定到适当的上下文

如果打算将回调绑定到适当的上下文,则最好在类构造函数中将其绑定一次:

export default class LandingPage extends Component {
   deleteStudent = this.deleteStudent.bind(this); // syntactic sugar for a constructor

   deleteStudent(e){
       console.log('hi', this, e )
   }

   render(){
       return(
           <div>
               <DisplayStudent studentData = {data}
                            deleteStudent = {this.deleteStudent}
            />
           </div>
       )
  } 
}

如果deleteStudent应该提供特定的参数,而不是在click事件(事件对象)中传递的参数,则更简单的方法是包装函数:

<button onClick={() => props.deleteStudent(ele.id)}>Delete</button

答案 4 :(得分:0)

完全不需要绑定2次。 Bind用于在函数内部传递此引用。因此,LandingPage“ DisplayStudent”内部的第一个绑定就足够了。将其绑定到构造函数中也是可见的,因为每次LandingPage重新渲染时,它都会向DisplayStudent传递新的功能参考。 onClick中的第二个绑定仅用于将参数传递给函数。

P.S。您可以使用箭头功能来避免此类混淆