こんにちは、habrauser。 どうやら、 私たちはすでに未来に住んでいるので、最近、ES6、ES7の新機能と、ReactとReduxによって提案された新しいアイデアを研究するために、しっかりと座りました。 そして彼は同僚のために彼の研究の昇華を概説した記事を書きました。 この記事は予想外に非常に膨大であることが判明し、私はそれを出版することにしました。 私たちのプロジェクトのプロプライエタリコードの提示と参照に矛盾があることを事前に謝罪しますが、JavaScriptの世界がどこに動いているか、そして何が起こっているのかを無視してはならない理由を理解するのに役立つことがあると思います。
コンポーネントモデル、クラス、デコレータ、ミックスイン、反応性、純粋な機能、不変のデータ構造、Reactの重要なアイデアに関する私の考えについてお話します。 私はReactユーザーではないことをすぐに言わなければならず、上記のすべては彼のドキュメントと彼のアーキテクチャを説明する技術記事を読んだ結果です。 つまり、いくつかの理想化された表現は、確かにそれが実際にどのようになっているかの単純化されたモデルにすぎません。
行きましょう。 過去数日間、私は世界で何が起こっているのか、どこへ移動するのか、何を見るのかを理解するために、最新のJavaScriptテクノロジーを継続的に研究してきました。 事実、私はかなり前から見回してきましたが、これまでのところ、ReactまたはES7によって提案されたアイデアを深く研究する時間を見つけることができませんでした。 私の経験では、このような環境を無視することは横向きであることが示されていますが、特に、私は勉強する必要があったからといって、コールバックに煩わされることに多くの時間を費やしていました約束 -何年も前に私は一般的にこのアイデアを知っていましたが。 そして、最後の犬がこの概念を使い始めたときだけ-私はこの素晴らしいアイデアを無視して、無駄にどれだけの時間を費やしたかを悟りました。 そして、私はおそらくそこについて何かを読む時間がないという事実によってこれを正当化します! これは非常に皮肉です。 何かに気づくだけでは十分ではありません-これを理解するには、座って何かを徹底的に研究する必要がある場合があります。
特に、ビジネスの商業的成功が依存する複雑さという点でかなり深刻なプロジェクトの実施に関しては、これが再び起こることを望まないでしょう。 時は金なり、時には1日よりも研究に少し時間を費やして、うまく機能しないメガトンのレガシーコードの真ん中に座っている方がよい場合があります。これは、リファクタリングおよびデバッグするよりも書き直しやすいです。 この動機により、数年前に私たちのフレームワークから多くの抽象化に取り組み始め、それが正当化されました。 そして今、世界がまったく同じ方向に動いていることを非常にうれしく思います。近年取り組んできたことはすべて、この間に大人気となった現代のJS技術にあります。 コンポーネント、特性/ミックスイン、タイプコントラクト、ユニットテスト、宣言性/機能性など...現在、5つのWebプロジェクトのうち4つがReactで記述されていますが、数年前にはReactについて誰も知りませんでした。 しかし、これはすべて、これらの積極的に開発されているすべてのテクノロジーがどのように配置されているかを見て、理解する必要があることを意味します。
一般に、私はコード内のすべてのことを調べ始め、これが長期的にどのように正当化されるか、および「店の隣人」にどのように実装されるかを批判的に評価し始めました。 そしてその過程で、私は多くの興味深いことを発見しました。そして、頭の中で受け取った情報からカオスを落ち着かせようとして数日間平和に眠ることができなかったものを見つけました。
コンポーネント
[注:独自の]フレームワークでは、すべてがプロトタイプを使用してクラスのセマンティクスを模倣するシステムに関連付けられており、それに追加機能が追加されています。
ToggleButton = $component ({
$depends: [DOMReference],
$required: {
label: 'string'
},
$defaults: {
color: 'red'
},
onclick: $trigger (),
toggled: $observable (false),
checked: $alias ('toggled'), //
coolMethod: $static ($debounce ($bindable ($memoize (function () { ... })))),
})
— $static
, $trigger
, $observable
, «» . , . $trigger
, .
, . , — . ES7 ( ), , — , - . , , , .
$depends
traits (), . , . , $defaults
, - . , recalcLayout
— , afterRecalcLayout
. observables. Traits traits. — require
. , .
this
— - :
button.touched (this.doLogout)
ES6
, JavaScript — , . . JS , ! , JavaScript - . — — - , . - . ES6 .
ES6 , (JSON), — -, -, , . , $memoize
, . $depends
— ES6 , $depends: [...]
, .
, ES6. , JavaScript - , class
new
! , :
- The rise of functional programming & the decline of Angular 2.0
- ES6 Classes Are Virus
- How to Escape the 7th Circle of Hell
- Not Awesome: ES6 Classes
TL/DR: , , Object.create
. , : new
, — «», .
, , ES6 — — (embedded DSL) , .
ES7
JS, , . , , , — :
Button = @component class {
@trigger onclick () {}
@observable toggled = false
@debounce @bindable @memoize static coolMethod () {}
}
, (), . , .
. , , — Chai Spies. , ES6/ES7, (Proxy Objects, Symbols).
, $required
$depends
- , . , JavaScript , :
class Button {
depends: [DOMReference]
@required label: 'string'
@required color: 'red'
, class public fields, - :
class Button {
depends = [DOMReference]
@required label = 'string'
@required color = 'red'
- ( proposal ) , ( ) , , — , - … , .
, . , @required label: 'string'
. , ? , , , — ...
Babel...
… , JavaScript-, . , Babel — , . !
— JavaScript, ES6/ES7/ES.Next JS, — . , . , public class fields — . Babel — . .
Babel, ES5 — IE. , .
Babel , , , - , . , . source maps — , , — .
React
, React. Facebook — , . , , : , , ...
Button = React.createClass ({
mixins: [SomeMixin]
propTypes: {
label: React.PropTypes.string.isRequired
},
render () { ... }
})
, React — - - . , React — . , 90% , «» — , Babel. .
, React ! , , , — , . React , , , , . , - — . — , — React, , . , , «» , FRP… , — , . , , — , . — .
, «» - :
ToggleButton = ({ label, toggled }) => <button toggled="{toggled}">{label}</button>
ToggleButton ({ label: '?', toggled: true }) // <button toggled="true">?</button>
, — , DOM. . — . - , WTF? , JavaScript c ?
«» ToggleButton
():
ToggleButton = $component ({
$required: { label: 'string' },
$defaults: { toggled: false },
render () { return <button checked="{this.toggled}">{this.label}</button> }
})
new ToggleButton ({ label: ' , -?', toggled: false }).render ()
, . , ? ! ( new
), — . — ES6 - .
— . . ? -, ES6 , destructuring-:
ToggleButton ({ label, toggled = false }) => ...
-, : Flow vs TypeScript. . , JavaScript. . Flow ( ) JavaScript — ToggleButton
:
ToggleButton = ({ label : String, toggled = false }) => <button toggled="{toggled}">{label}</button>
label
! «» — , run-time. , run-time — :
ToggleButton ({ toggled: false }) // label
, «» — , , — , map reduce...
, , - console.log
— , , . — , ! , — , . , . DOM, .
, — , . «» DOM- — , , . , , UI- — DOM . , - JSON-, , , toggled
, DOM — setAttribute ('toggled', toggled)
. , — , React, : «» , - console.log
:
ToggleButton = ({ label, toggled }) => <button toggled="{toggled}">{label}</button>
, React . , (ad-hoc) … , ! React , . « »: « -» — , - — React . , . . , « » , . , - — , — .
, , ?
channels « » — « ». , Promise — . , label
toggled
, « », . DOM , . , setAttribute ('toggled', toggled)
, , . , . map
, filter
, reduce
— … « » «», async
/await
. , — . , « » — - . « ».
React? , ! - , observables, , ( ) — , .
React, :
- — ,
- , - observable- — , «»
, , :
data = { todos: [ { toggled: true, label: '' }, { toggled: false, label: ' ' } ] }
DOM-:
TodoList = ({ todos }) =>
<h1></h1>
<content>{ todos.map (ToggleButton) }</content>
:
render (TodoList (data)) // - console.log
, «» render
. ToggleButton
TodoList
DOM — . - toggled
, ToggleButton
— . DOM, ? React "blueprint" ( React Virtual DOM) — DOM, — . - :
{ type: 'button', props: { toggled: true, children: [''] } }
, render
, DOM — . , , , diff. DOM. , ...
{ type: 'button', props: { toggled: true, children: [''] } }
{ type: 'button', props: { toggled: false, children: [''] } }
… setAttribute ('toggled', false)
DOM . , JavaScript- , DOM . — , DOM.
React : . . ?
React - , :
« » , « ». . DOM, VDOM, - — , VDOM ?
- VDOM — VDOM, , - . ?
React, .
VDOM — , . - (TodoList
, ToggleButton
) VDOM- — VDOM, — . . , - VDOM, «» , — , . , — . , , — . ! — ( ). ( ) . ! — ...
ToggleButton
? , , , ? VDOM, ? . , , VDOM? — ! ...
VDOM, - — , . , todos[1].toggled = true
— . , , TodoList
, todos
— — . «» , . , VDOM ! , - «» — , .
— — , … , , [1].toggled = true
, - :
todos = todos.set (1, Object.assign ({}, todos[1], { toggled: true }))
.set
— , , 1 — , . , DOM — .
, ( ) « » , — « , , ».
, , Immutable.js. , JavaScript — Object.freeze — , , .
, Proxy Objects, JavaScript, , :
todos = todos[1].toggled.set (true) // todos
«» !
Redux
, , Redux - . , undo/redo — , — — , React.
, React , — , Redux. , :
- — (previous state → new state)
- (-)
, - :
addTodo (oldState, label) => ({ todos: oldState.todos.concat ({ label: label, checked: false }) })
checkTodo (oldState, index) => ({ todos: ...
( , ), Redux:
reduce (oldState, action) => {
switch (action.type) {
case ADD_TODO: return { todos: oldState.todos.concat ({ label: action.label, checked: false }
case CHECK_TODO: return { ...
, … .
, - — . , «» React — , — React , . - , - - DOM . , « » . React Fiber Architecture, , - - , , . , Prerequisites — .