不再需要绑定React组件类中的函数吗?

时间:2019-07-06 09:45:30

标签: javascript reactjs bind arrow-functions

我刚刚注意到,如果定义了普通的类组件函数,则不再需要在类构造函数中绑定这些函数了(因此,即使我不使用ES6公共类字段语法),我也可以正常地通过这些函数通过onClick = {this.someFunction}传递给我的事件处理程序,而无需事先将它们绑定到我的类上,并且当执行本机DOM事件(或React案例中的综合事件)时,也不会向我抛出错误。而且,无论我使用箭头函数作为事件处理程序还是仅传递函数引用也没关系...

这是React的新功能吗?我认为几个月前还没有此功能。

编辑:这是一些代码示例,它是一个简单的新闻提要api应用,其中索引具有一个通过点击处理程序传递的ListItem子组件...

import {React, Component, fetch, API_KEY, BASE_URL} from '../config/config';
import ListComponent from '../components/ListComponent';
import PropTypes from 'prop-types';
import { makeStyles } from '@material-ui/core/styles';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import { List } from '@material-ui/core';


const useStyles = makeStyles(theme => ({
  root: {
    width: '100%',
    height: 400,
    maxWidth: 360,
    backgroundColor: theme.palette.background.paper,
  },
}));

export default class index extends Component { 
    constructor(props) {
        super(props);
        this.state = {
            news: this.props.news
        }
    }   


    static async getInitialProps() {
        let querystring = `${BASE_URL}top-headlines?q=sex&fsortBy=popularity&apiKey=${API_KEY}`;
        console.log(querystring);
        let news =  await fetch(querystring);
        news = await news.json();
        //console.log("NEWS:",news.articles);
        return {
            news: news.articles
        }
    }

    getOutput (e) {
        console.log("Item ",e," was clicked!");
    }

    render() {
        return (
            <div>
                {                    
                   this.state.news.map((news,index) => (
                    // <ListItem button 
                    // key={index} 
                    // onClick={e => this.getOutput(e)}>
                    // <ListItemText primary={`${news.title}`} />
                    // </ListItem>
                    <ListComponent 
                    index = {index}
                    news = {news}
                    clicked = {this.getOutput}
                    />
                    )
                   )

                }
            </div>
        )
    }
}

这是“列表”子组件:

import React from 'react'    

export default function ListComponent({index,clicked,news}) {
    return (
        <li key={index} onClick ={clicked}>
            {
                news.title
            }
        </li>
    )
}

我刚刚对其进行了测试,并且成功了!注意:这是Next.js的示例,但是我也在普通的React-app(使用create-react-app创建)中对其进行了测试,并且可以与相同的示例一起使用... 当我单击列表项时,将获得控制台输出:

Item  Class {dispatchConfig: {…}, _targetInst: FiberNode, nativeEvent: MouseEvent, type: "click", target: li, …}  was clicked!

2 个答案:

答案 0 :(得分:1)

这与react无关,但是与JavaScript的classthis的工作方式有关。

在您的示例中,您没有得到错误,因为您没有做错任何事情。尽管当您想调用this.setState或通过this引用任何内容时,由于this不会引用您认为的内容,您可能会收到错误或意外的结果,它将引用触发的元素事件。

为什么带有arrow functions的类字段可以在不硬绑定this的情况下“解决”问题?因为他们用自己的方式“处理” this上下文,但实际上他们什么都不做。意思就是包装执行上下文中的this引用,就是在箭头函数中获得的引用。

顺便说一下,class field函数和class methods之间的区别在于,类方法是在原型上创建的,而字段是在实例上创建的。 < / p>

我制作了一个简单的流程图,可以帮助您了解给定上下文(总是从上到下,顺序很重要)this所引用的内容

enter image description here

答案 1 :(得分:0)

这不是React的新功能。您可以从类内部访问任何函数或属性,而无需绑定。进行绑定(或声明箭头函数)的原因是将局部this连接到全局上下文,以便它可以引用类(父函数)。尝试在getOutput函数中使用例如this.props,将会出现错误。