【问题标题】:ReactJS. How to call component's method from parent component反应JS。如何从父组件调用组件的方法
【发布时间】:2017-12-11 17:08:29
【问题描述】:

我的例子是一个简单的订单。 我有一个主组件 (Order),在这个组件内我呈现子组件的动态列表 (OrderLine)

class Order extends React.Component {
  ...
  render() {
    return <div>
      <strong>Total: $ {this.getTotal()}</strong>
      <table id='orderlines' style={tableStyles}>
        <tbody>
          {this.getLines()}
        </tbody>
      </table>
    </div>
  }

  getLines = () => {
    return this.state.orderLines.map((item, _) =>
      <OrderLine key={item.id} {...item} />)
  }
}

子组件 (OrderLine) 具有输入 (quantity) 和方法 getTotal(),用于计算该行的总和

getTotal = () => (this.props.product.price * this.state.quantity).toFixed(2);

目标是计算订单的总和。

我想做类似sum(map(allOrderLines, (line) =&gt; line.getTotal())) 的操作,但我无法从Order 组件访问orderLine.getTotal()

那么,最好的方法是什么?我知道如何从孩子更新父母的状态(将回调函数作为道具),但是可以从父母那里做到吗?

此处为完整示例:

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    将 ref 实例附加到您的订单行并调用该函数

    orderLinesRef = [];
    getLines = () => {
        return this.state.orderLines.map((item, _) => (
          <OrderLine
            key={item.id}
            ref={ref => (this.orderLinesRef[_] = ref)}
            updateCallback={this.updateTotal}
            {...item}
          />
        ));
      };
    

    【讨论】:

    • 很高兴有帮助:)
    【解决方案2】:

    你可以像这样将ref添加到order line

    getLines = () => {
    return this.state.orderLines.map((item, _) =>
      <OrderLine 
      ref={instance => this.myOrder = instance}
        key={item.id} 
        updateCallback={this.updateTotal}
        {...item} 
      />)
    

    现在您可以通过this.myOrder 访问OrderLine 的方法

    【讨论】:

    • 它只适用于一行。但是如果订单线不止一个呢? this.myOrder.append(instance)也许
    【解决方案3】:

    我认为最简单的选择是将 getTotal 移动到父 Order 组件中,并将其作为道具传递给每个 OrderLine。然后,两个组件都可以访问该实用程序功能。

    Order.js

    render() {
        const { id, product } = this.props;
        return (
          <tr key={id}>
            ...
            <td>
              {this.props.getTotal(this.props.product.price, this.state.quantity)}
            </td>
          </tr>
        );
      }
    

    OrderLine.js

      updateTotal = () => {
        // You'll need a way to get the product price and quantity for each order line
        let total = this.state.orderLines.reduce((sum, line) => {
          sum = sum + this.getTotal(line.product.price, line.quantity);
        }, 0);
    
        this.setState({ total });
      };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-27
      • 2021-05-02
      • 2019-08-10
      • 1970-01-01
      • 2018-06-08
      相关资源
      最近更新 更多