Изучите React.JS за 8 минут

React.JS - это библиотека Javascript для построения пользовательских интерфейсов. Это быстро, легко и весело работать.

После прочтения этой статьи, которая, по утверждениям Medium, займет у вас 8 минут, вы сможете приступить к написанию приложений на React, если вы хорошо знакомы с Javascript.

Кроме того, не забудьте также ознакомиться с нашим курсом Learn React For Free на Scrimba, если вы хотите узнать больше:

Компоненты

React построен на компонентах, а не на шаблонах. Вы создаете компонент, вызывая метод createClass для объекта React - точки входа в библиотеку.

Нравится:

var ButtonApp = React.createClass({
    render: function(){
        return (
            <input type="submit" />
        );
    }
});

Метод createClass принимает один аргумент - объект спецификации. Этот объект содержит все методы для данного класса компонентов. Самым важным из них является метод render (), который запускается, когда компонент готов к отрисовке на странице.

В нем вы вернете описание того, что вы хотите, чтобы React отображал на странице. В приведенном выше случае мы просто хотим, чтобы он отображал кнопку.

Примечание. Функция рендеринга - это описание пользовательского интерфейса в любой момент времени. Поэтому, если данные в нем изменяются, React позаботится об обновлении пользовательского интерфейса соответствующим образом.

JSX - Расширение синтаксиса Javascript

Синтаксис HTML на самом деле не HTML, а нечто, называемое JSX. Это просто расширение синтаксиса для Javascript, которое позволяет писать JS с тегами, подобными XML. Таким образом, теги на самом деле являются вызовами функций, которые преобразуются в код React.JS и, наконец, превращаются в HTML и Javascript в DOM.

Но пока вы можете просто думать об этом как о HTML / XML с некоторыми дополнительными возможностями.

Примечание. Вы можете писать JSX как в файлах .js, так и в файлах .jsx, но вам необходимо преобразовать его из JSX в React.JS с помощью транспилятора или препроцессора.

Несколько компонентов

Если вы хотите вложить несколько компонентов вместе, вы делаете это в операторе return функции рендеринга, как мы делаем ниже, где мы встраиваем ButtonForm в приложение компонент. На данный момент компонент Приложение владеет компонентом ButtonForm. Это тот тип родительско-дочерних отношений, который вы, вероятно, узнаете из HTML.

var ButtonForm = React.createClass({
    render: function(){
        return (
            <div>
                <h3>Click the button</h3>
                <input type="submit" />
            </div>
        );
    }
});
var App = React.createClass({
    render: function(){
        return (
            <div>
                <h1> Welcome to my button app!</h1>
                <ButtonForm />
            </div>
        );
    }
});
React.render(<App />,  document.getElementById("content"));

Метод React.render (), который вы видите ниже двух компонентов, выполняет «кикстарт» рендеринга и отображает корневой компонент (в данном случае приложение) в DOM. в указанном контейнере.

Хорошая привычка - создать макет своего пользовательского интерфейса до того, как вы начнете кодировать, и разделить компоненты с помощью цветов. Ниже приведен пример того, как структура компонентов в React может выглядеть визуально для простого приложения Todo:

Реквизит и состояние

В React есть два типа данных; реквизит и состояние. Поначалу различие между ними немного сложно понять, по крайней мере, концептуально. Но как только вы начнете кодировать, вам быстро удастся отделить их друг от друга.

Ключевое отличие состоит в том, что состояние является частным и может быть изменено внутри самого компонента. Свойства являются внешними и не контролируются самим компонентом. Он передается от компонентов выше по иерархии, которые также контролируют данные.

Таким образом, хотя компонент не может напрямую изменять свои собственные свойства (он может делать это косвенно, но давайте оставим это на потом), он может изменить свое собственное состояние.

Реквизит

Мы начнем с более внимательного изучения реквизита, так как он заставляет нас понимать один направленный поток данных в Reacts, о котором также важно знать.

Давайте инициализируем наше кнопочное приложение некоторыми данными, используя props. Сначала нам нужно откуда-то получить данные. Это можно сделать, например, с помощью вызова Ajax для получения некоторых данных из API, но пока мы просто жестко закодируем это как переменную:

var BUTTONTEXT = "Click the button";

Способ передачи этих данных в свойства компонента очень похож на то, как вы указываете атрибут HTML-элемента.

<App text={BUTTONTEXT} />

Причина, по которой мы заключаем BUTTONTEXT в фигурные скобки, заключается в том, что нам нужно сообщить JSX, что мы хотим добавить выражение Javascript.

Как только компонент App инициализирован таким образом, он может получить доступ к переменной BUTTONTEXT через this.props.text. Однако он не может напрямую изменять данные. С точки зрения компонентов, его свойства неизменны. Это просто то, чем он инициализирован.

Вот пример:

var BUTTONTEXT = "Click the damn button";
    var ButtonForm = React.createClass({
        render: function(){
            return (
                <div>
                    <h3>{this.props.text}</h3>
                    <input type="submit" />
                </div>
            );
        }
    });
    var App = React.createClass({
        render: function(){
            return (
                <div>
                    <h1> Welcome to my button app!</h1>
                    <ButtonForm text={this.props.text} />
                </div>
            );
        }
    });
    React.render(<App text={BUTTONTEXT} />,  document.getElementById("content"));

Свойства передаются в компонент Приложение в React.render (). Компонент Приложение теперь может получить доступ к переменной BUTTONTEXT через this.props.text; он также может передавать данные своим собственным потомкам, как и делает. Он инициализирует компонент ButtonForm с теми же свойствами, что и сам; мы просто передаем данные по цепочке.

Когда данные достигают компонента ButtonForm, они находят свое место назначения, так как они отображаются как текст описания в теге h3 над кнопкой.

Этот способ передачи реквизита по цепочке - от родителя к потомку - это то, как данные распределяются в React. Он передается по иерархии и передается как опора.

Состояние

Другой способ хранения данных в React - состояние компонента. И в отличие от свойств, которые неизменны с точки зрения компонентов, состояние является изменяемым.

Поэтому, если вы хотите, чтобы данные в вашем приложении изменялись - например, на основе взаимодействия с пользователем - они должны храниться в состоянии компонента где-то в приложении.

Поскольку состояние является частным и принадлежит только одному компоненту, его нельзя передать по цепочке дочерним компонентам. Если вы хотите передать данные ребенку, вам нужно будет передать их как опору.

Состояние инициализации

Чтобы инициализировать состояние, просто передайте компоненту getInitialState () и верните любое состояние, с которым вы хотите, чтобы ваш компонент был инициализирован.

Изменение состояния

Чтобы изменить состояние, просто вызовите this.setState (), передав новое состояние в качестве аргумента.

var App = React.createClass({
    getInitialState: function(){
        return {
            active: true
        }
    },
    handleClick: function(){
        this.setState({
            active: !this.state.active
        });
    },
    render: function(){
        var buttonSwitch = this.state.active ? "On" : "Off";
        return (
            <div>
                <p>Click the button!</p>
                <input type="submit" onClick={this.handleClick} />
                <p>{buttonSwitch}</p>
            </div>
        );
    }
});
React.render(<App />,  document.getElementById("content"));

Этот фрагмент также заставит вас познакомиться с системой событий Reacts, но не беспокойтесь, это очень просто. Мы подключаем прослушиватель событий к кнопке, ожидая события onClick. Когда это срабатывает, мы вызываем функцию handleClick, которая доступна через ключевое слово this.

Затем функция handleClick вызывает this.setState (), который переключает активную переменную между истиной и ложью.

Примечание. События React являются синтетическими; они являются кроссбраузерными оболочками для собственных событий браузера, а это означает, что библиотека гарантирует, что выбранное вами событие одинаково работает во всех браузерах.

Где должно жить государство?

Вы должны стараться сохранить как можно меньше компонентов с отслеживанием состояния, а также минимизировать объем данных в состоянии. Если компоненты, расположенные ниже по иерархии, нуждаются в доступе к данным из состояния, просто передайте данные вниз как свойства.

Компоненты с отслеживанием состояния обычно находятся на более высоком уровне, а компоненты без состояния - на более низком уровне.

Чтобы выяснить, где должно жить государство, вы можете задать себе вопросы, взятые из оригинальной React docs:

  • Определите каждый компонент, который что-то отображает на основе этого состояния.
  • Найдите общий компонент-владелец (один компонент выше всех компонентов, которым требуется состояние в иерархии).
  • Государством должен владеть либо общий владелец, либо другой компонент на более высоком уровне иерархии.
  • Если вы не можете найти компонент, для которого имеет смысл владеть состоянием, создайте новый компонент просто для хранения состояния и добавьте его где-нибудь в иерархии над компонентом общего владельца.

Обратный поток данных

Мы много говорили о том, что в React данные передаются только в одном направлении; от родителя к ребенку. Это не совсем так, поскольку можно добавить обратный поток данных.

Это понадобится, когда компоненту, находящемуся в глубине иерархии, необходимо изменить состояние своего родителя.

Ниже приведен пример того, как нажатие кнопки в компоненте ButtonForm вызывает изменение состояния в компоненте App над ним, поскольку он может получить доступ к onUserClick функция.

var ButtonForm = React.createClass({
    render: function(){
        return (
            <div>
                <input type="submit" onClick={this.props.onUserClick} />
                <h3>You have pressed the button {this.props.counter} times!</h3>
            </div>
        );
    }
});
var App = React.createClass({
    getInitialState: function(){
        return {
            counter: 0
        }
    },
    onUserClick: function(){
        var newCount = this.state.counter + 1;
        this.setState({
            counter: newCount
        });
    },
    render: function(){
        return (
            <div>
                <h1> Welcome to the counter app!</h1>
                <ButtonForm counter={this.state.counter} onUserClick={this.onUserClick} />
            </div>
        );
    }
});
React.render(<App />,  document.getElementById("content"));

Как видите, мы просто передаем метод onUserClick в качестве свойства, позволяя компоненту ButtonForm подключаться к компоненту App. , и вызвать один из его методов.

ссылки и findDOMNode

Иногда вам может потребоваться проникнуть в DOM и внести некоторые изменения, но не обязательно задействовать состояние или свойства. В таких ситуациях вам нужно будет захватить выбранный вами узел.

К счастью, React предоставляет удобный способ захвата узлов DOM. Просто вызовите React.findDOMNode (component), передав компонент по вашему выбору.

Чтобы получить ссылку на выбранный вами компонент (или element =, вы можете использовать атрибут refs. Просто добавьте ref к такому элементу:

<input ref="textField" ... />

Изнутри компонента, отображающего указанный выше тег ввода, вы можете ссылаться на поле ввода через this.refs.textField.

Давайте посмотрим на правильный пример:

var ButtonForm = React.createClass({
        focusOnField: function(){
            React.findDOMNode(this.refs.textField).focus();
        },
        render: function(){
            return (
                <div>
                    <input 
                        type="text"
                        ref="textField" />
                    <input 
                        type="submit"
                        value="Focus on the input!" 
                        onClick={this.focusOnField} />
                </div>
            );
        }
    });
    var App = React.createClass({
        render: function(){
            return (
                <div>
                    <h1> Welcome to the focus app!</h1>
                    <ButtonForm />
                </div>
            );
        }
    });
    React.render(<App />,  document.getElementById("content"));

Это приведет к тому, что текстовое поле ввода будет выделено, когда вы нажмете кнопку.

Атрибут key

Когда вы создаете компоненты динамически, каждому из них нужен уникальный атрибут key. Нравится:

var App = React.createClass({
    getInitialState: function(){
        return {
            todos: ["get food","drive home","eat food", "sleep"] 
        }
    },
    render: function(){
        var todos = this.state.todos.map(function(todo,index){
            return <li key={index}>{todo}</li>
        });             
        return (
            <div>
                <h1> Welcome to the ToDo list!</h1>
                <ul>
                    {todos}     
                </ul>
            </div>
        );
    }
});

Конечно, есть гораздо больше, чтобы узнать о React, но если вы понимаете все вышеизложенные концепции, вы знаете достаточно, чтобы начать создавать приложения React. На этом мы остановимся.

Следующим шагом для вас будет выполнение этого упражнения, в котором вы создадите простое приложение со списком Todo.

Это первое упражнение в курсе React.JS для начинающих, который я устраиваю в Нью-Йорке на следующей неделе. Если вы продолжите упражнение 2 и 3 в репозиториях, вы быстро станете профессионалом в React!

Удачи!

PS: Если вы зашли так далеко, вы можете просто нажать кнопку с сердечком ниже :)

Спасибо за прочтение! Меня зовут Пер Борген, и я в основном пишу об изучении нового.

Не стесняйтесь обращаться ко мне, если у вас есть вопросы или вы хотите подключиться, через Twitter, GitHub или просто старый адрес электронной почты: [email protected].