ReactJS:我如何使用内部组件setState?

时间:2016-02-26 10:48:19

标签: reactjs react-jsx react-intl

"use strict";

import React, { Component, PropTypes } from 'react';
import { FormattedNumber } from 'react-intl';
import $ from 'jquery';

const Increase = require('../Increase').default;

class Quotation extends Component {
  constructor(props) {
    super(props);
    this.state = {
      last: undefined,
      prevClose: undefined
    };
  }

  componentDidMount() {
    this.loadFromServer(this.props.url);
    setInterval((() => {
      this.loadFromServer(this.props.url);
    }).bind(this), this.props.pollInterval);
  }

  loadFromServer(url) {
    $.ajax({
      url: url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({last: parseFloat(data.ticker.last)});
        this.setState({prevClose: parseFloat(data.ticker.prev_close)});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(url, status, err.toString());
      }
    });
  }

  number(n) {
    if (n == undefined) {
      return '...'
    }
    return (
      <FormattedNumber
        value={n}
        maximumFractionDigits={2}
        minimumFractionDigits={2}
      />
    );
  }

  render() {
    return (
      <div className="quotation">
        <div className="title">{this.props.children}</div>
        <div className="last-price">
          {this.number(this.state.last)}
        </div>
        <Increase last={this.state.last}
                  prevClose={this.state.prevClose} />
      </div>
    );
  }
}

Quotation.propTypes = {
  url: PropTypes.string.isRequired,
  pollInterval: PropTypes.number.isRequired,
  children: PropTypes.string.isRequired
};

Quotation.getDefaultProps = {
};

export default Quotation;

增加使用react-intl,下面是测试:

component = TestUtils.renderIntoDocument(
  <IntlProvider locale='en'>
    <Quotation url="https://test.com" pollInterval={1000}>
      BTC / CNY
    </Quotation>
  </IntlProvider>
);

it('quotation unloaded', () => {
  const quotation = TestUtils.findRenderedDOMComponentWithClass(
    component, 'quotation'
  );
  let lastPrice = TestUtils.findRenderedDOMComponentWithClass(
    component, 'last-price'
  );
  quotation.setState({last: 1100, prevClose: 1000});// can't access it
  expect(lastPrice.textContent).toEqual(1100);
});

我正在测试我的reactJS组件。

因为我使用了react-intl。我必须使用IntlProvider来渲染它。

如何设置Quotation的状态?

更新 我用:

let quotation = TestUtils.findRenderedComponentWithType(
  component, Quotation
);

获得了QuotationsetState

但又出现了另一个错误:

https://github.com/yahoo/react-intl/issues/332#issuecomment-189394004

1 个答案:

答案 0 :(得分:0)

我没有测试这种方法。只是猜测。

docs您需要将 className 属性设置为您的组件。在您的示例中,您将找到 DIV 元素而不是您的组件。请尝试以下方法:

component = TestUtils.renderIntoDocument(
  <IntlProvider locale='en'>
    <Quotation className="findme" url="https://test.com" pollInterval={1000}>
      BTC / CNY
    </Quotation>
  </IntlProvider>
);

it('quotation unloaded', () => {
  const quotation = TestUtils.findRenderedDOMComponentWithClass(
    component, 'findme'
  );
  let lastPrice = TestUtils.findRenderedDOMComponentWithClass(
    component, 'last-price'
  );
  quotation.setState({last: 1100, prevClose: 1000});// can't access it
  expect(lastPrice.textContent).toEqual(1100);
});

有效吗?