【问题标题】:No need to bind functions in React Component Classes anymore?不再需要在 React 组件类中绑定函数了吗?
【发布时间】:2019-07-06 09:45:30
【问题描述】:

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

这是 React 的新特性吗?我想几个月前,这个功能还没有..

编辑:这是一些代码示例,它是一个简单的新闻提要 api 应用程序,其中 index 有一个 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>
        )
    }
}

这是 List 子组件:

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!

【问题讨论】:

  • 请发布您正在使用的代码。
  • 您当时是否在回调中访问 this 上下文中的任何内容?正如前面评论者所说,分享你的代码,然后更容易测试和验证你所看到的(还有reactjs版本,babel版本,...)
  • 您是否尝试过在 getOutput 函数中执行 this.setState 或与关键字 this 相关的操作?
  • @Muljayan 编辑:好的,如果我尝试设置状态,它又是旧的行为,我想这就是问题所在,因为它只显示我是否想访问类属性,比如它具有的状态由于缺少范围而无法访问;P 好的对不起伙计们我的愚蠢错误呵呵

标签: javascript reactjs bind arrow-functions


【解决方案1】:

这与 react 无关,而是 JavaScript 的 classthis 是如何工作的。

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

为什么使用arrow functions 的类字段“解决”问题而不硬绑定this?因为他们以他们“处理”this 上下文的方式,实际上他们没有做任何事情。意思是,包装执行上下文中的 this 引用是什么,这就是您将在箭头函数中获得的引用。

顺便说一句,class field 函数和class methods 的区别在于,类方法是在原型上创建的,而字段是在实例上创建的。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 是的,你是对的,我想这就是 this 绑定的全部目的和老问题;P
    猜你喜欢
    • 2016-02-14
    • 2016-10-30
    • 2019-11-15
    • 2018-07-24
    • 2021-04-15
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 2016-12-01
    相关资源
    最近更新 更多