ruk·si

⚛️ React
Basics

Updated at 2017-02-11 13:01

React is a user interface component library. The main selling point is its virtual DOM; React maintains a copy of your DOM, all changes first go there and only the differences between virtual and the real DOM are updated.

React removes the need to have separate template files. Component functionality and HTML structure are defined in the same place by using JSX syntax.

React is declarative. Components re-render themselves automatically when they change; this is done by passing props to child components and modifying own state.

React is all about creating components. You define components using createClass where render tells how it's shown. Then you use ReactDOM.render to render the component.

var Greeting = React.createClass({
   render: function() {
       return <h1>Hello from component Z.</h1>
   }
});

ReactDOM.render(<Greeting/>, document.body);

React moves single point of truth from DOM/JS to JavaScript. This makes React a lot more maintainable than jQuery and bindings.

render method in component needs to return a single HTML element. Returning multiple root DOM elements will break in some cases. <div> is the most used root element and will work in most of the cases.

Components have properties props. Properties are set passed to component like HTML attributes when the it's created.

var Avatar = React.createClass({
    getDefaultProps: function() {
        return { path: 'default path :(' }
    },
    render: function() {
        return (
            <div>
                <img src={this.props.path}>
            </div>
        )
    }
});

ReactDOM.render(<Avatar path="url"/>, document.body);

Components have a state state. If the value can change in the lifetime of the component, store it as state, not as a property.

var Counter = React.createClass({
    getInitialState: function() {
        return { count: 0 };
    },
    add: function() {
        this.setState({
            count: this.state.count + 1;
        });
    },
    subtract: function() {
        this.setState({
            count: this.state.count - 1;
        });
    },
    render: function() {
        return (
            <div>
                <h1>Count: {this.state.count}</h1>
                <button onClick={this.subtract}>-</button>
                <button onClick={this.add}>+</button>
            </div>
        )
    }
})

React.render(<Counter/>, document.body);

Component should never modify it's own properties Properties are the main way how parent component communicates with its children. If you need to store and modify variables inside a component, use state.

var TaskApp = React.createClass({
    getInitialState: function() {
        return {
            items: [],
            task: ''
        }
    },
    onChange: function(e) {
        this.setState({task: e.target.value});
    },
    addTask: function(e) {
        e.preventDefault();
        this.setState({
            items: this.state.items.concat([this.state.task]),
            task: ''
        });
    },
    render: function() {
        return (
            <div>
                <h1>My Tasks</h1>
                <TaskList items={this.state.items} />
                <form onSubmit={this.addTask}>
                    <input onChange={this.onChange} value={this.state.task} />
                    <button>Add Task</button>
                </form>
                </form>
            </div>
        )
    }
});

var TastList = React.createClass({
    render: function() {
        var displayTast = function(task) {
            return <li>{task}</li>
        }
        return (
            <ul>
                { this.props.items.map(displayTask) }
            </ul>
        )
    }
});

You add HTML classes to components with className. class is a reserved word in JavaScript.

# BAD
<form class="download-box">
    <button>Download</button>
</form>

# GOOD
<form className="download-box">
    <button>Download</button>
</form>

You can access other components with refs. Usually you should use props and states, but sometimes you need to gain access to the DOM element.

var StopWatch = React.createClass({
    getInitialState: function() {
        return {
            time: 0
        };
    },
    onChange: function(e) {
        this.setState({until: e.target.value});
    },
    onClick: function() {
        React.findDOMNode(this.refs.buttony).disabled = true;
        this.interval = setInterval(function() {
            this.tick();
            if (this.isTimeUp()) {
                this.finish();
            }
        }.bind(this), 1000);
    },
    tick: function() {
        this.setState({time: this.state.time + 1});
    },
    isTimeUp: function() {
        return this.state.time == this.state.until;
    },
    finish: function() {
        console.log('Finished!');
        this.setState({time: 0, until: ''});
        React.findDOMNode(this.refs.inputty).focus();
        React.findDOMNode(this.refs.buttony).disabled = false;
        return clearInterval(this.interval);
    },
    render: function() {
        return (
            <div>
                <input ref="inputty" onChange={this.onChange} value={this.state.until} />
                <button ref="buttony" onClick={this.onClick}>Go</button>
                <h1>{this.state.time}</h1>
            </div>
        )
    }
});