React-在组件之间传递方法引用

时间:2018-10-18 12:20:40

标签: javascript reactjs

目前,我正在参加有关Udemy的关于React的课程。

现在的选择是关于传递方法引用。因此,基本上讲师将方法引用作为道具传递给App.js的render方法内的Person标签。在Person组件中,单击按钮时将执行switchNameHandler,而在修改输入文本字段时将执行nameChangedHandler。

因此,课程讲师使用.bind()方法。我已经研究了bind()方法的作用。但是在当前示例中,我有两个问题:

  1. 在当前示例中,此关键字指的是两个(App.js中的第二个人标签=> click值)?据我了解的代码,他采取this.switchNameHandler类的当前方法,并将其再次绑定到当前类(我知道没有道理)吗?这两个处理程序方法是该类的一部分,对我而言这没有意义,因为您通常将类外部的匿名函数绑定到对象。

  2. 为什么讲师(在第二个Person标签中)使我们在switchNameHandler中而不是在nameChangedHandler中使用bind方法?


App.js

import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person'

class App extends Component {

  state = {
    persons: [
      { name: 'Peter', age: 20 },
      { name: 'Manu', age: 28 },
      { name: 'Stephanie', age: 24 }
    ],
    otherState: 'some other value'
  }

  switchNameHandler = (newName) => {
    //console.log('Was clicked!');
    this.setState({
      persons: [
        { name: newName, age: 20 },
        { name: 'Manu', age: 5 },
        { name: 'Stephanie', age: 30 }
      ]
    })
  }

  nameChangedHandler = (event) => {
    this.setState({
      persons: [
        { name: 'Max', age: 20 },
        { name: event.target.value, age: 5 },
        { name: 'Stephanie', age: 30 }
      ]
    })
  }

  render() {
    return (
      <div className="App">
        <h1>Hi, I'm a React App</h1>
        <button onClick={() => this.switchNameHandler('Maximilian!!!!!')}>Switch Name</button>
        <Person
          name={this.state.persons[0].name}
          age={this.state.persons[0].age}></Person>
        <Person
          name={this.state.persons[1].name}
          age={this.state.persons[1].age}
          click={this.switchNameHandler.bind(this, 'Max!')}
          changed={this.nameChangedHandler}>My hobbies: Racing</Person>
        <Person
          name={this.state.persons[2].name}
          age={this.state.persons[2].age}></Person>
      </div>
    );
  }
}

export default App;


Person.js

import React from 'react';
import './Person.css';

const person = (props) => {
    return (
        <div className="Person">
            <p onClick={props.click}>I'm { props.name } and I am { props.age } years old!</p>
            <p>{props.children}</p>
            <input type="text" onChange={props.changed} value={props.name} />
        </div>

    )
};

export default person;

添加了React文档的: 我正在阅读反应文档(https://reactjs.org/docs/faq-functions.html),并且只有这一行:

如果需要访问处理程序中的父组件,则还需要将该函数绑定到组件实例(见下文)。

绑定渲染:(来自反应站点的代码)

class Foo extends Component {
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick.bind(this)}>Click Me</button>;
  }
}

在我们的例子中,处理程序方法不在父组件中,而在同一组件中。在这种情况下,我也必须理解一些错误。

3 个答案:

答案 0 :(得分:1)

如果您不绑定该函数,而仅将其作为参数传递,例如:

<Person
  name={this.state.persons[1].name}
  age={this.state.persons[1].age}
  click={this.switchNameHandler}
  changed={this.nameChangedHandler}>My hobbies: Racing</Person>

您将如上所述定义函数。当您尝试访问App实例时,将得到未定义的消息:

switchNameHandler(newName){
    console.log(this);// undefined
}

但是在您的情况下,switchNameHandler是箭头功能。根据{{​​3}}文档

  

直到箭头函数,每个新函数都定义了自己的此值(根据函数的调用方式,在构造函数中为新对象,在严格模式函数调用中未定义,如果该函数被称为“对象方法”等)

但是即使知道这一点,为什么还要绑定函数呢?因为:

  1. 您需要保留上下文(应用程序的this
  2. 传递一个附加参数('Max!'

要回答第二个问题:nameChangedHandler不需要绑定,因为它具有箭头功能,并且可以使用创建它的上下文。

答案 1 :(得分:0)

第一种情况(click={this.switchNameHandler.bind(this, 'Max!')})只是这样,您无需声明额外的函数即可将参数传递给function。最后,最终结果与上面的示例(onClick={() => this.switchNameHandler('Maximilian!!!!!')})相同,不同之处在于,在第一种情况下,它创建了一个箭头函数(which automatically binds this)来调用带有自定义参数的方法第二个将参数与this绑定在一起(创建一个新的函数对象)。

第二种情况(changed={this.nameChangedHandler}),由于this is automatically bound to arrow functions(并且此函数被声明为箭头函数),因此当作为prop传递时,您无需再次绑定它。

答案 2 :(得分:0)

有两种功能:

    您使用 function 关键字声明的
  1. 函数

这种函数具有一个名为 this 的变量,该变量表示调用对象的上下文,可以隐式或显式传递。

const obj = {
   test: function() {
          console.log(this)
         }
}

obj.test();
test();
const bindedTest = obj.test.bind(obj);
bindedTest();

在前面的示例中,我们使用 obj 的上下文调用了测试函数,因此它表示或等于obj(打印obj)。如果您在没有上下文的情况下调用该函数,则编译器将在窗口对象上下文(浏览器环境中的javascript全局对象)中搜索该函数。最后一次调用时,您首先将此词绑定到 obj 上下文,然后可以在任何地方使用它而不会丢失该绑定。

function test () {
   console.log(this)
}

test();

在第二个示例中,您在没有上下文的情况下调用函数测试,而上下文未显式定义上下文,然后使用窗口对象上下文调用了函数。

  1. 箭头功能

箭头功能没有。如果您在箭头函数中使用 this ,它将无法在其上下文中找到名为this的变量,因此它将在较高的上下文中搜索该变量,依此类推,直到为其找到一个值。

const obj = {
     test: () => {
         console.log(this)
         }
}

obj.test();

在前面的示例中,我使用 obj 的上下文调用了测试函数。但是箭头函数没有this,因此它在上限范围(即全局对象(窗口))中搜索上下文。

  • 现在在react所有方法中必须有一个this上下文引用 他们所在的班级。
  • 如果使用箭头功能,则无需绑定 当您调用它时,该函数将在上方搜索this 作用域是类上下文。
  • 如果使用函数声明,则必须绑定 this 因为该函数将使用窗口上下文来调用 参考错误,因此我们将this绑定到类上下文。
  

就您而言,您不必在任何可能的地方绑定 this   直接使用它,因为您使用了箭头功能。