Статьи

Использование JSX и React

Конечный продукт
Что вы будете создавать

JSX похож на смесь XML и HTML. Вы используете JSX в коде React, чтобы легко создавать компоненты для своих приложений. JSX превращается в JavaScript, когда React компилирует код.

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

Вот пример использования JSX для рендеринга HTML:

js var div = <div className="foo" />; ReactDOM.render(div, document.getElementById('example'));

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

« `js var MyComponent = React.createClass ({/ /}); var myElement = <MyComponent someProperty = {true} />;

ReactDOM.render (myElement, document.getElementById (‘пример’)); « `

Примечание. В JSX есть зарезервированные слова, поскольку в конце концов это по сути JavaScript, поэтому такие ключевые слова, как class и for не рекомендуется использовать в качестве имен атрибутов. Вместо этого компоненты React ожидают имена свойств React, например, такие как className и htmlFor .

Укажите детей внутри вашего JSX следующим образом:

« `js var Пользователь, Профиль;

// Вы пишете в JSX: var app = щелчок ;

// Что будет выводиться в JS: var app = React.createElement (User, {className: ”vip-user”}, React.createElement (Profile, null, “click”)); « `

Используйте Babel REPL, чтобы проверить JSX.

Создать форму легко с помощью JSX и его подкомпонентов, например:

« `js var Form = FormComponent;

var App = (

); « `

Чтобы это работало, вы должны создать подкомпоненты как атрибуты основного компонента:

« `js var FormComponent = React.createClass ({…});

FormComponent.Row = React.createClass ({…}); FormComponent.Label = React.createClass ({…}); FormComponent.Input = React.createClass ({…}); « `

Чтобы использовать JavaScript для создания результата для использования в значении атрибута, React просто нужно, чтобы вы завернули его в {} фигурные скобки следующим образом:

« `js // Вы пишете в JSX: var myUser = <User username = {window.signedIn? window.username: »} />;

// станет в JS: var myUser = React.createElement (Пользователь, {username: window.signedIn? Window.username: »}); « `

Вы также можете просто передать логическое значение для атрибутов формы, таких как disabled , checked и т. Д. Эти значения также могут быть жестко запрограммированы, если хотите, просто написав простой HTML.

« `js // Сделать поле обязательным ; <input type = ”text” name = ”username” required = {true} />;

// Проверяем по умолчанию <input type = ”checkbox” name = ”RememberMe” value = ”true” checked = {true} />;

// Включить поле <input type = ”text” name = ”captcha” disabled = {false} /> « `

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

Добавьте несколько свойств к вашему компоненту, используя новый оператор распространения ES6.

js var props = {}; props.username = username; props.email = email; var userLogin = <userLogin {...props} />;

Вы можете использовать эти переменные пропа несколько раз. Если вам нужно переопределить одно из свойств, это можно сделать, добавив его к компоненту после оператора ... spread, например:

js var props = { username: 'jimmyRiddle' }; var userLogin = <userLogin {...props} username={'mickeyFinn'} />; console.log(component.props.username); // 'mickeyFinn'

Вы можете использовать как многострочные комментарии // и /* ... */ внутри вашего JSX. Например:

« `js var components = (

{/ * дочерний комментарий, поместите {} вокруг * /} <Пользователь / * многострочный комментарий здесь * / name = {window.isLoggedIn? window.name: »} // Здесь комментарий в конце строки />

); « `

Есть несколько вещей, которые могут запутать некоторых людей с помощью JSX, например, при добавлении атрибутов к собственным элементам HTML, которых нет в спецификации HTML.

React не будет отображать атрибуты для собственных элементов HTML, которых нет в спецификации, если вы не добавите префикс data- следующим образом:

« « HTML

« `

Кроме того, рендеринг HTML в динамическом контенте может сбить с толку из-за экранирования и встроенной React защиты XSS. По этой причине React предоставляет dangerouslySetInnerHTML .

js <div dangerouslySetInnerHTML={{__html: 'Top level &raquo; Child'}} />

Возможно, вы видели приложение Gitter . Это приложение для онлайн-чата, предназначенное в основном для разработчиков. Многие люди используют его для обсуждения своих проектов на GitHub, благодаря его простой интеграции с GitHub и возможности создания канала для вашего хранилища.

Приложение такого типа может быть легко создано с помощью React путем реализации API WebRTC для создания чата p2p в браузере. Для этого мы будем использовать модули PeerJs и socket.io для Node.

Чтобы дать вам четкое представление об архитектуре приложения, вот базовая низкоуровневая диаграмма UML:

файл

ChatServer получает сигнальные сообщения с PeerJS, и каждый клиент будет использовать его в качестве прокси для обеспечения прохождения NAT.

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

json { "name": "react-webrtc-chat", "version": "0.0.0", "description": "React WebRTC chat with Socket.io, BootStrap and PeerJS", "main": "app.js", "scripts": { "start-app": "node app.js", "start": "npm run start-app" }, "keywords": [ "webrtc", "react" ], "license": "MIT", "dependencies": { "express": "~4.13.3", "peer": "~0.2.8", "react": "~0.12.2", "react-dom": "^0.14.1", "socket.io": "~1.0.6" }, "devDependencies": { "babel-preset-react": "^6.0.14", "babelify": "^7.1.0", "browserify": "^12.0.1" } }

Этот файл package.json используется npm для простой настройки вашего приложения. Мы указываем наши зависимости: express , веб-фреймворк, который мы будем использовать для обслуживания нашего приложения; peer , сервер peerjs, который мы будем использовать для сигнализации; socket.io который будет использоваться для опроса и реализации webRTC. react-bootstrap и bootstrap — пакеты для использования CSS-фреймворка Twitter для стилизации нашего приложения.

Нам также понадобятся дополнительные пакеты, и для этого мы будем использовать bower .

Создайте bower.json и добавьте следующее:

json { "name": "react-webrtc-chat", "main": "app.js", "version": "0.0.0", "ignore": [ "**/.*", "node_modules", "bower_components", "public/lib", "test", "tests" ], "dependencies": { "react": "~0.12.2", "jquery": "~2.1.4", "eventEmitter": "~4.2.7", "peerjs": "~0.3.14", "bootstrap": "~3.3.5" } }

В этой конфигурации мы eventEmitter react , jQuery , bootstrap , eventEmitter для eventEmitter событий и клиентскую библиотеку peerJS для переноса WebRTC.

Наконец, укажите, где это установить, установив файл .bowerrc :

json { "directory": "src/lib" }

Отсюда, просто сидеть сложа руки и установить свои зависимости с помощью:

bash $ bower install && npm install

После выполнения этой команды вы увидите новый каталог node_modules и src/lib . Они содержат модули, готовые к использованию.

Теперь создайте app.js в главном каталоге вместе с package.json и т. Д. Это будет основной точкой входа вашего приложения.

« `js // Настройка наших сервисов var express = require (‘express’), PeerServer = require (‘peer’). PeerServer, events = require (‘./ src / Events.js’), app = express () , port = process.env.PORT || 3001;

// Сообщаем экспрессу использовать каталог ‘src’ app.use (express.static (__dirname + ‘/ src’));

// Настройка http-сервера и PeerJS-сервера var expressServer = app.listen (port); var io = require (‘socket.io’). listen (expressServer); var peer = новый PeerServer ({порт: 9000, путь: ‘/ chat’});

// Вывести на печать некоторые данные консоли console.log (‘#### — Сервер работает — ####’); console.log («Прослушивание порта», порт);

peer.on (‘connection’, function (id) {io.emit (events.CONNECT, id); console.log (‘# Connected’, id);});

peer.on (‘отключить’, функция (id) {io.emit (events.DISCONNECT, id); console.log (‘# Disconnected’, id);}); « `

Это просто создаст сервер Express, сделав src/ файлы, которые мы только что получили с bower теперь доступными через HTTP. Затем был socket.io экземпляр socket.io для прослушивания объекта expressServer . Это используется для опроса и облегчения следующего шага для PeerServer , который на самом деле выполняет часть чата WebRTC.

Чтобы настроить PeerServer , все, что вам нужно сделать, это указать port и path на котором будет работать сервер, а затем начать настройку событий с .on метода .on . Мы используем отдельный файл с именем Events.js чтобы указать события нашего приложения.

js peer.on('connection', function (id) { io.emit(events.CONNECT, id); console.log('# Connected', id); });

Здесь мы используем событие events.CONNECT чтобы указать, когда пользователь подключился к нашему приложению. Это будет использоваться состояниями наших компонентов представления для обновления их дисплеев в режиме реального времени.

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

Создайте файл в src/Server.js и добавьте следующее:

« `js / * global EventEmitter, events, io, Peer * / ‘use strict’;

function ChatServer () {EventEmitter.call (this); this._peers = {}; }

ChatServer.prototype = Object.create (EventEmitter.prototype);

ChatServer.prototype.onMessage = function (cb) {this.addListener (events.MSG, cb); };

ChatServer.prototype.getUsername = function () {вернуть this._username; };

ChatServer.prototype.setUsername = function (username) {this._username = username; };

ChatServer.prototype.onUserConnected = function (cb) {this.addListener (events.CONNECT, cb); };

ChatServer.prototype.onUserDisconnected = function (cb) {this.addListener (events.DISCONNECT, cb); };

ChatServer.prototype.send = function (пользователь, сообщение) {this._peers [пользователь] .send (сообщение); };

ChatServer.prototype.broadcast = function (msg) {for (var peer in this._peers) {this.send (peer, msg); }};

ChatServer.prototype.connect = function (имя пользователя) {var self = this; this.setUsername (имя пользователя); this.socket = io (); this.socket.on (‘connect’, function () {self.socket.on (events.CONNECT, function (userId) {if (userId === self.getUsername ()) {return;} self._connectTo (userId ); self.emit (events.CONNECT, userId); console.log (‘Пользователь подключен’, userId);}); self.socket.on (events.DISCONNECT, function (userId) {if (userId === self .getUsername ()) {return;} self._disconnectFrom (userId); self.emit (events.DISCONNECT, userId); console.log (‘Пользователь отключен’, userId);});}); console.log («Соединение с именем пользователя», имя пользователя); this.peer = new Peer (имя пользователя, {host: location.hostname, порт: 9000, путь: ‘/ chat’}); this.peer.on (‘open’, function (userId) {self.setUsername (userId);}); this.peer.on (‘connection’, function (conn) {self._registerPeer (conn.peer, conn); self.emit (events.CONNECT, conn.peer);}); };

ChatServer.prototype._connectTo = function (имя пользователя) {var conn = this.peer.connect (имя пользователя); conn.on (‘open’, function () {this._registerPeer (имя пользователя, conn);} .bind (this)); };

ChatServer.prototype._registerPeer = function (имя пользователя, conn) {console.log (‘Регистрация’, имя пользователя); this._peers [имя пользователя] = conn; conn.on (‘data’, function (msg) {console.log (‘Message Receive’, msg); this.emit (events.MSG, {content: msg, author: username});} .bind (this) ); };

ChatServer.prototype._disconnectFrom = function (имя пользователя) {удалить this._peers [имя пользователя]; }; « `

Это основные внутренности приложения. Здесь мы настраиваем объект ChatServer со всеми его функциями.

Сначала мы используем socket.io чтобы установить сигнализацию нового пользователя, подключенного через events.CONNECT следующим образом:

js ChatServer.prototype.connect = function (username) { var self = this; this.setUsername(username); this.socket = io(); this.socket.on('connect', function () { self.socket.on(events.CONNECT, function (userId) { if (userId === self.getUsername()) { return; } self._connectTo(userId); self.emit(events.CONNECT, userId); console.log('User connected', userId); });

Затем, чтобы подключиться к PeerServer, мы используем следующее:

js this.peer = new Peer(username, { host: location.hostname, port: 9000, path: '/chat' });

Затем мы прослушиваем события с помощью метода on :

js this.peer.on('open', function (userId) { self.setUsername(userId); }); this.peer.on('connection', function (conn) { self._registerPeer(conn.peer, conn); self.emit(events.CONNECT, conn.peer); });

У нас также есть наши внутренние компоненты JSX в каталоге components/chat . Не торопитесь, чтобы просмотреть все из них в хранилище. Сейчас я сосредоточусь на компоненте ChatBox :

« `js / ** @jsx React.DOM * /

«использовать строгое»;

var ChatBox = React.createClass ({

getInitialState: function () {return {users: []}; },

componentDidMount: function () {this.chatProxy = this.props.chatProxy; this.chatProxy.connect (this.props.username); this.chatProxy.onMessage (this.addMessage.bind (это)); this.chatProxy.onUserConnected (this.userConnected.bind (это)); this.chatProxy.onUserDisconnected (this.userDisconnected.bind (это)); },

userConnected: function (user) {var users = this.state.users; users.push (пользователь); this.setState ({users: users}); },

userDisconnected: function (user) {var users = this.state.users; users.splice (users.indexOf (user), 1); this.setState ({users: users}); },

messageHandler: function (message) {message = this.refs.messageInput.getDOMNode (). value; this.addMessage ({content: message, автор: this.chatProxy.getUsername ()}); this.chatProxy.broadcast (сообщение); },

addMessage: function (message) {if (message) {message.date = new Date (); this.refs.messagesList.addMessage (сообщение); }},

render: function () {return (<div className = «chat-box» ref = «root»> <div className = «chat-header ui-widget-header»> React p2p Web RTC Chat </ div> <div className = «строка-chat-content-wrapper»> <UsersList users = {this.state.users} username = {this.props.username} ref = ”usersList”> </ UsersList>
</ div> <MessageInput ref = ”messageInput” messageHandler = {this.messageHandler}> </ MessageInput> </ div>); }}); « `

Этот класс использует ChatServer мы создали ранее, используя его в качестве прокси для компонента ChatBox .

Наконец, все компоненты и библиотеки отображаются на странице с помощью index.html и index.html помощью узла express.

Чтобы запустить приложение, запустите npm start и в браузере укажите http://localhost:3001 чтобы взглянуть на чат.

С Heroku обслуживать из облака очень просто. Зарегистрируйте бесплатную учетную запись, и тогда вы сможете установить heroku инструмент heroku в свою систему. Узнайте больше о настройке Heroku в Центре разработки Heroku .

Теперь, когда у вас есть Heroku , войдите в систему и создайте новый проект следующим образом:

bash $ git clone [email protected]:tomtom87/react-p2p-chat.git $ cd react-p2p-chat $ heroku create Creating sharp-rain-871... done, stack is cedar-14 http://sharp-rain-871.herokuapp.com/ | https://git.heroku.com/sharp-rain-871.git Git remote heroku added

Здесь вы получите случайное имя от Heroku и URL своего приложения — в нашем примере это http://sharp-rain-871.herokuapp.com/ . Heroku также создает git-репо для этого приложения.

Теперь это так же просто, как подтолкнуть ваш код к героку:

bash $ git push heroku master

Как только загрузка будет завершена, вы сможете запустить свой веб-сервис следующим образом:

bash $ heroku ps:scale web=1

Теперь просто перейдите по указанному URL-адресу или в качестве ярлыка используйте команду open следующим образом:

bash $ heroku open

Вы узнали, как создавать компоненты JSX и связывать их с React, с подробным примером приложения чата. Потратьте некоторое время, чтобы просмотреть код и посмотреть, как работают React и каталог components/chat .

В сочетании с развертыванием в Heroku вы можете приступить к взлому и созданию собственных приложений React для облака!