Javascript 为什么我需要在map范围内绑定这个arrow函数?

Javascript 为什么我需要在map范围内绑定这个arrow函数?,javascript,reactjs,ecmascript-6,arrow-functions,Javascript,Reactjs,Ecmascript 6,Arrow Functions,我试图在li上使用onClick事件显示数组对象中的数组,我使用的是arrow函数,但我发现我需要将函数绑定到map的范围内,这是为什么?这难道不是arrow函数消除绑定需求的目的吗 class ListRecipes extends React.Component { showIngredients = (item) => { console.log(item.ingredients) } render() { const { l

我试图在li上使用onClick事件显示数组对象中的数组,我使用的是arrow函数,但我发现我需要将函数绑定到map的范围内,这是为什么?这难道不是arrow函数消除绑定需求的目的吗

 class ListRecipes extends React.Component   {

    showIngredients = (item) => {
        console.log(item.ingredients)
    }

    render() {
    const { list } = this.props;
    let Recipe = list.map((item, index) => {
        let boundClick = this.showIngredients.bind(this, item);
        return <li key={index} onClick={boundClick}> {item.recipeName} </li>
    })
    return (
        <div>
            <ul>
                {Recipe}
            </ul>
        </div>
        )
    }
}
类ListRecipes扩展了React.Component{
ShowComponents=(项目)=>{
console.log(item.components)
}
render(){
const{list}=this.props;
让配方=列表.映射((项目,索引)=>{
让boundClick=this.showComponents.bind(此,项);
return
  • {item.recipeName}
  • }) 返回(
      {Recipe}
    ) } }
    另外,从上面返回新函数的代码之间有什么区别

    class ListRecipes extends React.Component   {
    
        showIngredients = (item) => (event) => {
            console.log(item.ingredients)
        }
    
        render() {
        const { list } = this.props;
        let Recipe = list.map((item, index) => {
            return <li key={index} onClick={this.showIngredients(item)}> {item.recipeName} </li>
        })
        return (
            <div>
                <ul>
                    {Recipe}
                </ul>
            </div>
            )
        }
    }
    
    类ListRecipes扩展了React.Component{
    ShowComponents=(项目)=>(活动)=>{
    console.log(item.components)
    }
    render(){
    const{list}=this.props;
    让配方=列表.映射((项目,索引)=>{
    return
  • {item.recipeName}
  • }) 返回(
      {Recipe}
    ) } }
    当您编写
    onClick={this.showComponents(item)}
    时,您并没有将函数引用分配给onClick,而是调用它

    你可以把它改成

    let Recipe = list.map((item, index) => {
        return <li key={index} onClick={() => this.showIngredients(item)}> {item.recipeName} </li>
    })
    
    let Recipe=list.map((项目、索引)=>{
    return
  • this.showComponents(item)}>{item.recipeName}
  • })

    同样使用
    let boundClick=this.showComponents.bind(此项)
    您正在将
    showComponents
    函数绑定到上下文,并向其传递一个额外的参数,由于bind返回一个新函数,因此,
    boundClick
    是一个函数,稍后将其分配给
    onClick

    ,我认为通常首选此代码:

    let boundClick = this.showIngredients.bind(this, item);
    

    您正在绑定要传递给ShowComponents函数的项。因此,您最终将创建items.length单独的函数引用数,每个函数引用都绑定到此项和当前项

    在做其他事情之前,我们需要了解onClick上回调侦听器中传递的参数是。 那意味着

    function myMethod(event) {
      // only event is passed as argument
    }
    <div onClick={myMehtod}/>
    
    函数myMethod(事件){
    //只有事件作为参数传递
    }
    
    那个么问题是你们怎么能传递额外的论点呢?简单。从侦听器中调用所需的方法

    function calculate(item){
      // no event trace here
    }
    
    <div onClick={function(event) { calculate(item) }}/>
    // OR better, fat arrow
    <div onClick={event => calculate(item)}/>
    
    功能计算(项目){
    //这里没有事件跟踪
    }
    //或者更好,肥箭
    计算(项目)}/>
    
    记住,胖箭头总是绑定到这个范围,而不是原型

    class Component {
      scopedMethod = () => {
         this.name = 'John';
      }
      prototypeMethod() {
        this.name = 'John';
      }
      render() {
        return (
          <div>
            {/* works */}
            <button onClick={this.scopedMethod}/>
            {/* OOPS, 'this' is event rather then component */}
            <button onClick={this.prototypeMethod}/>
            {/* works */}
            <button onClick={() => this.prototypeMethod()}/>
            {/* works */}
            <button onClick={this.prototypeMethod.bind(this)}/>
          </div>
        )
      }
    }
    
    类组件{
    scopedMethod=()=>{
    this.name='John';
    }
    原型方法(){
    this.name='John';
    }
    render(){
    返回(
    {/*作品*/}
    {/*OOPS,“this”是事件而不是组件*/}
    {/*作品*/}
    this.prototypeMethod()}/>
    {/*作品*/}
    )
    }
    }
    

    希望这能给我们带来曙光。所以问题是什么时候,为什么我会使用范围绑定方法而不是原型方法,反之亦然?嗯,原型方法很便宜。始终尝试使用它们。但是,一些开发人员正在避免使用lambda函数(渲染内部的生成函数),因为它可能会导致性能问题。当您需要在10秒内重新渲染组件时,新的lambda将在10秒内创建

    如果你不绑定它会发生什么?没有绑定的代码到底是什么样子的?如果我没有绑定它或返回一个新的事件函数,它会在加载页面时记录数组,但不会再次单击showComponents=(item)=>{console.log(item.Components)}`
    onClick={this.showComponents(item)}
    我知道这一点,但他们说要避免内联函数。@Juan好吧,那就是
    bind
    了。这与箭头函数和
    this
    的值无关,仅当您调用该函数时。@Shubham感谢您的回答,我还想知道返回新事件和后代码中的绑定之间的区别。请检查此答案,了解如何避免渲染中的绑定