thewire
thewire

Reputation: 57

React: convert createClass to ES6 class

I would like to convert code with createClass to ES6 classes. I'm having some trouble when it comes to the class with the getInitialState function.

Below is the code I am trying to convert:

var StockRow = React.createClass({
    render: function () {
        var lastClass = '',
            changeClass = 'change-positive',
            iconClass = 'glyphicon glyphicon-triangle-top';
        if (this.props.stock === this.props.last) {
            lastClass = this.props.stock.change < 0 ? 'last-negative' : 'last-positive';
        }
        if (this.props.stock.change < 0) {
            changeClass = 'change-negative';
            iconClass = 'glyphicon glyphicon-triangle-bottom';
        }
        return (
            <tr>
                <td>{this.props.stock.symbol}</td>
                <td>{this.props.stock.open}</td>
                <td className={lastClass}>{this.props.stock.last}</td>
                <td className={changeClass}>{this.props.stock.change} <span className={iconClass} aria-hidden="true"></span></td>
                <td>{this.props.stock.high}</td>
                <td>{this.props.stock.low}</td>              
            </tr>
        );
    }
});

var StockTable = React.createClass({
    render: function () {
        var items = [];
        for (var symbol in this.props.stocks) {
            var stock = this.props.stocks[symbol];
            items.push(<StockRow key={stock.symbol} stock={stock} last={this.props.last} />);
        }
        return (
            <div className="row">
            <table className="table-hover">
                <thead>
                    <tr>
                        <th>Symbol</th>
                        <th>Open</th>
                        <th>Last</th>
                        <th>Change</th>
                        <th>High</th>
                        <th>Low</th>
                    </tr>
                </thead>
                <tbody>
                    {items}
                </tbody>
            </table>
            </div>
        );
    }
});

var HomePage = React.createClass({
    getInitialState: function() {
        var stocks = {};
        feed.watch(['MCD', 'BA', 'BAC', 'LLY', 'GM', 'GE', 'UAL', 'WMT', 'AAL', 'JPM']);
        feed.onChange(function(stock) {
            stocks[stock.symbol] = stock;
            this.setState({stocks: stocks, last: stock});
        }.bind(this));
        return {stocks: stocks};
    },
    render: function () {
        return (
            <div>
                <StockTable stocks={this.state.stocks} last={this.state.last}/>
            </div>
        );
    }
});

This is what I have for the first two:

class StockRow extends React.Component{
    constructor(props, context) {
        super(props, context);
    }
    render: function () {
        var lastClass = '',
            changeClass = 'change-positive',
            iconClass = 'glyphicon glyphicon-triangle-top';
        if (this.props.stock === this.props.last) {
            lastClass = this.props.stock.change < 0 ? 'last-negative' : 'last-positive';
        }
        if (this.props.stock.change < 0) {
            changeClass = 'change-negative';
            iconClass = 'glyphicon glyphicon-triangle-bottom';
        }
        return (
            <tr>
                <td>{this.props.stock.symbol}</td>
                <td>{this.props.stock.open}</td>
                <td className={lastClass}>{this.props.stock.last}</td>
                <td className={changeClass}>{this.props.stock.change} <span className={iconClass} aria-hidden="true"></span></td>
                <td>{this.props.stock.high}</td>
                <td>{this.props.stock.low}</td>              
            </tr>
        );
    }
}

class StockTable extends React.Component{
    constructor(props, context) {
        super(props, context);
    }
    render: function () {
        var items = [];
        for (var symbol in this.props.stocks) {
            var stock = this.props.stocks[symbol];
            items.push(<StockRow key={stock.symbol} stock={stock} last={this.props.last} />);
        }
        return (
            <div className="row">
            <table className="table-hover">
                <thead>
                    <tr>
                        <th>Symbol</th>
                        <th>Open</th>
                        <th>Last</th>
                        <th>Change</th>
                        <th>High</th>
                        <th>Low</th>
                    </tr>
                </thead>
                <tbody>
                    {items}
                </tbody>
            </table>
            </div>
        );
    }
}

However, I am unsure how to approach the final class, especially with respect to the getInitialState function.

Any help would be appreciated!

EDIT:

Here is what I have for the third class:

class HomePage extends React.Component{
    constructor(props, context) {
        super(props, context);
        this.state = {
            stocks = {}
        }

    }
    getData() {
        var stocks = {};
        feed.watch(['MCD', 'BA', 'BAC', 'LLY', 'GM', 'GE', 'UAL', 'WMT', 'AAL', 'JPM']);
        feed.onChange(function(stock) {
            stocks[stock.symbol] = stock;
            this.setState({stocks: stocks, last: stock});
        }.bind(this));
        return {stocks: stocks};
    }
    componentDidMount() {
        this.getData();
    }
    render: function () {
        return (
            <div>
                <StockTable stocks={this.state.stocks} last={this.state.last}/>
            </div>
        );
    }
}

Upvotes: 0

Views: 322

Answers (2)

Vakaren
Vakaren

Reputation: 111

You can't use stocks in your constructor since you don't have access to it yet (unless you pass down an initial value via props). You can initialize it and update the state later, e.g. in componentDidMount():

constructor(props) {
  super(props)
  this.state = {
    stocks = {}
  }
}

componentDidMount() {
  // fetch stocks and this.setState({ stocks })
}

Upvotes: 0

raphaelSeguin
raphaelSeguin

Reputation: 434

You must replace getInitialState by initializing the state variable in the constructor.

constructor(props, context) {
    super(props, context);
    state = {stocks}
}

If you have to fetch some values to initialize the state properly, you can do it in the componentDidMount method

componentDidMount() {
    fetchInfos().then( infos => this.setState({...infos}) );
}

Upvotes: 1

Related Questions