在状态组件中选择正确的函数调用方式

时间:2018-06-19 11:21:52

标签: javascript reactjs

例如,我很难理解/理解在javascript类中调用方法的正确方法

考虑我们有状态状态组件,例如

addIngredientHandler = (type) => { //Adds one to the state of ingredient }

purchasingHandlerOpen =  () =>   this.setState({purchasing: true}) //will show a order summary pop-up if we have more than one ingredient 

我们通过将它们都返回给子组件(使用props),方法是通过返回这样的有状态组件来调用它们

  <BuildControls           
       ingredientAdded={this.addIngredientHandler} 
       purchasingHandlerOpen={this.purchasingHandlerOpen}
       purchasableHandler={this.state.purchasable} />

在无状态子组件中,我们进行

<BuildControl
       ingredientAdded={() => props.ingredientAdded(el.type)}
      />))}
      <button className={Classes.OrderButton} disabled={!props.purchasableHandler} onClick={props.purchasingHandlerOpen}>Order</button>
  </div

在这里我们已经在一个地方使用了

 ingredientAdded={() => props.ingredientAdded(el.type)}

和另一个

onClick={props.purchasingHandlerOpen}>

所以我的问题是什么时候我们使用{() => props.ingredientAdded(el.type)}调用方法/函数,什么时候使用{props.purchasingHandlerOpen},什么时候做类似{{1} }

轻微注意:在上面的示例中,我做

{props.purchasingHandlerOpen()}

如果我执行诸如<button className={Classes.OrderButton} disabled={!props.purchasableHandler} onClick={props.purchasingHandlerOpen}>Order</button> 之类的操作会引发无限渲染错误消息,则我执行{props.purchasingHandlerOpen()}之类的操作该按钮将不起作用。

2 个答案:

答案 0 :(得分:1)

首先,您必须了解要传递给我们的东西只是函数,所以这两种方式没有什么本质上的不同

尽管有几点需要考虑:

首先:由于react.js使用浅表比较,因此每次传递

ingredientAdded={() => props.ingredientAdded(el.type)} 

您实际上正在传递刚刚创建的函数,因此它可能会导致您的子级render函数不必要的调用(尽管您可以通过使用shouldComponentUpdate来避免这种情况)。这可能会导致较大的反应树上出现性能问题,因此首选第二种方法。

第二:您可以通过第一种方法轻松地混合一些值,例如

ingredientAdded={() => props.ingredientAdded(el.type, SOMETHING_FROM_STATE)}

第三。通过生成返回函数的函数,您可以轻松地修改事件处理程序并将其传递到反应树中:

class App extends React.Component {
  generateFunction(something) {
    return (arg) => {
      this.props.myFunction(something, arg)
    }
  }

  render() {
   return (
     <div>
       <FirstComponent onClick={this.generateClickFunction('First')} />
       <SecondComponent onClick={this.generateClickFunction('Second')} />
     </div>
   }
  }
}

UPD

onClick应该始终接收函数,而不是其结果,例如:

<button ... onClick={props.purchasingHandlerOpen} />

如果您将onClick更改为{props.purchasingHandlerOpen()},则说明您正在调用该函数,因此会将其结果传递给props。

如果您将onClick更改为{() => purchasingHandlerOpen},则传递的是未定义的(它不是props.purchasingHandlerOpen,但purchasingHandlerOpen是未定义的),因此React认为没有回调传递给道具

答案 1 :(得分:-1)

{() => props.ingredientAdded(el.type)}创建一个绑定el.type的新功能,请参见arrow functions

{props.purchasingHandlerOpen}不执行任何操作,因为我们不执行该函数(没有(), call, apply)。我们只需传递函数引用即可。

{props.purchasingHandlerOpen()}运行该功能。