在React中暴露组件方法

Expose Component Method in React

本文关键字:组件 方法 暴露 React      更新时间:2023-09-26

我在React中更新值时遇到问题。

我有一个组件,当点击时增加和减少一个值。这部分正常工作,但我遇到的问题是将其暴露给另一个组件的另一部分,以便它与数字的总和相对应。

基本上,我有一个需要更新的数量,并且有一个显示选择总数的计数。还要注意,这也会更新一个美元金额。例如,一个价格将是10美元,如果我选择5,那么总数将是5,价格将是50美元。

任何帮助都将是非常感激的。

组件:数量

import React from 'react';
import If from '../utils/helpers';

var QuantityInput = React.createClass({
  getInitialState: function() {
    return {
      quantity: 0
    };
  },
  handleIncrement: function(e) {
    this.props.handleIncrement(this.props.quantity + 1);
  },
  handleDecrement: function(e) {
    if (this.props.quantity > 1) {
      this.props.handleDecrement(this.props.quantity - 1);
    }
  },
  handleChange: function(e) {
    var value = e.target.value.replace(/[^0-9]/, '');
    value = (value == '' ? 1 : value);
    value = parseInt(value);
    this.setState({
      quantity: value
    });
  },
  render: function() {
    return (
      <div className="quantity-input">
        <span className="button button--gray controls__quantity" onClick={this.handleDecrement}>-</span>
        <div className="quantity" onChange={this.handleChange}>{this.state.quantity}</div>
        <span className="button button--gray controls__quantity" onClick={this.handleIncrement}>+</span>
      </div>
    );
  }
});
module.exports = QuantityInput;

产品:

import React from 'react';
import If from '../utils/helpers';
import QuantityInput from '../components/quantity.js'

var Product = React.createClass({
  getInitialState: function() {
    return {
      quantity: 0
    }
  },
  handleIncrement: function(e) {
    this.setState({
      quantity: this.state.quantity + 1
    });
  },
  handleDecrement: function(e) {
    if (this.state.quantity > 1) {
      this.setState({
        quantity: this.state.quantity - 1
      });
    }
  },
  render: function() {
    var content;
    if (this.props.items.length > 0) {
      this.props.items.map(function(product) {
        var items = product.priceCode.map(function(priceCode) {
          return (
            <div className="list-item" key={priceCode.priceCode_id}>
              <div className="list-info list-info--cart">
                <div className="list-info__venue">
                  <h3 className="event-title">{priceCode.priceCode_title}</h3>
                  <If condition={priceCode.priceCode_passcode}>
                    <input type="text" placeholder="Passcode" />
                  </If>
                  <span className="event-details">{priceCode.priceCode_info}</span>
                </div>
              </div>
              <div className="controls">
                <div className="list-info__price">${priceCode.priceCode_price}</div>
                <QuantityInput />
              </div>
            </div>
          )
        });
        content = {items}
      });
    }
    return (
      <div>
        {content}
      </div>
    );
  }
});
var ProductContainer = React.createClass({
  getInitialState: function() {
    return {
      data: [],
      quantity: 0
    }
  },
  componentWillMount: function() {
    this.loadProducts(this.props.url);
  },
  loadProducts: function(url) {
    $.ajax({
      url: url,
      dataType: 'json',
      success: function(data) {
        this.setState({
          data: data
        });
      }.bind(this),
      error: function(xhr, status, err, data) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  _hasData: function() {
    var displayedItems = this.state.data.filter(function(product) {
      var match = product.priceCode.filter(function(priceCode) {
        return priceCode.priceCode_title.toLowerCase();
      });
      return (match !== -1);
    }.bind(this));
    return (
      <div>
        <Product items={displayedItems} />
      </div>
    ); 
  }, 
  render: function() {
    if (this.state.data) {
      return (
        <div className="price-code">
          {this._hasData()}
          <div className="subtotal-wrapper">
            <a href="#" className="button button--gray">Clear Selections</a>
            <div className="subtotal">
              Subtotal ({this.state.quantity}):
            </div>
            <a href="#" className="button">Find Tickets</a>
          </div>
        </div>
      )          
    } else {
      return <div>Loading...</div>;
    }
    return false
  }
});
module.exports = ProductContainer;

在React中,最好让数据流在应用程序中"下游"。我建议将数量作为状态属性放在Product组件中,然后在同一组件中定义增量/递减函数。QuantityInput将接收这些函数作为道具,并在onClicks被触发时调用它们。

下面是一个处理程序的例子(在QuanityInput中称为)…

handleIncrement: function(e) {
  this.props.handleIncrement(this.props.quantity + 1);
},

这允许您在实际产品上操作状态,而不是将其锁定在子组件中。您总是可以查看refs,但这并不是获取状态的最佳实践。

编辑:就像"原生"道具一样,你只需像这样将它们传递给子组件:

<QuantityInput handleIncrement={this.handleIncrement} handleDecrement={this.handleDecrement}/>