在React中将函数传递给组件

时间:2018-06-22 00:38:58

标签: javascript reactjs ecmascript-6

假设我有一个名为“父母”的类组件,该类组件呈现了一个名为“孩子”的组件:

class Parent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            someProperty = 'some value',
        };
}

setProperty: newValue => {
    this.setState({someProperty: newValue});
}

render() {
    return < Child setProperty: {this.setProperty} />
}

和子组件:

const Child = props => {
    return <button onClick={props.setProperty('new value')} />
}

所以这可行,并且对我来说很有意义:我们正在传递对setProperty的引用,然后只要单击子组件,该引用就可以。

在许多教程中,我在父母中看到以下代码:

render() {
    return < Child setProperty: {newValue => this.setProperty(newValue) />
}

传递函数时这样做有好处吗?

2 个答案:

答案 0 :(得分:2)

  

传递函数时这样做有好处吗?

这取决于如何定义this.setProperty。要么不必这样做,要么必须 ** ,因为否则它将无法工作。

这全都取决于this的工作方式:

在“正常”函数中,this的值取决于函数的调用方式。因此,如果this.setProperty是这样的普通函数,则使用setProperty={this.setProperty}将其传递给子函数将使子函数无法调用子函数,因此this引用父组件,这意味着在函数内调用this.setState将会失败。

function callMe(callback) {
  callback();
}

const obj = {
  foo: 42,
  normalFunction() {
    console.log(this.foo);
  },
};

callMe(obj.normalFunction); // not 42 :(
callMe(() => obj.normalFunction()); // 42 :)

但是,如果函数是箭头函数(如您的第一个示例)或绑定函数,则this的值已经预先确定,并且函数的调用方式无关紧要。

function callMe(callback) {
  callback();
}

const obj = {
  foo: 42,
  normalFunction() {
    console.log(this.foo);
  },
};
obj.boundFunction = obj.normalFunction.bind(obj);

callMe(obj.boundFunction); // 42 :)
callMe(() => obj.boundFunction()); // 42 :)


相关:

-

**:当然,如果可以控制如何定义函数,则以任何特定方式传递函数都是不必要的。整个答案仅着眼于为什么有人可能这样做的原因。如果更改函数的定义方式,则可以避免使用某种样式。

答案 1 :(得分:1)

因此,关于内联函数存在一些有争议的讨论。许多人认为内联函数性能不佳,并且特别是在使用PureComponent的情况下,也会使子组件重新呈现功能引用不同的原因。

恕我直言,对我来说没有什么区别,但是为什么在任何情况下都不能使用静态功能

这只是一个示例,演示了使用静态函数和内联函数之间的区别:

class Test extends Component {
  render() {
    return(
      <button onClick={() => this.props.onUpdate(true)}>update</button>
    )
  }
}

// could be this as handleClick is the same reference in all renders
class Test2 extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    this.props.onUpdate(true);
  }
  render() {
    return (
      <button onClick={this.handleClick}>update</button>
    );
  }
}

更新: 用构造函数绑定静态函数