Redux 公式ドキュメントのリポジトリ→ GitHub fork → GitBook の連携

以前から勝手に OSS ドキュメントの翻訳をしてはこのブログに公開していましたが、読みにくいというクレームをよく頂いておりました。しかし、そうは言われても、公式ページと同じ公開方式 (例えば GitHub Pages や GitBook 形式がよく使われています) で翻訳した結果を公開するのは、少し自分には難しい…と思っておりました。

が、ついに綺麗なフォーマットで公開できそうです。

Redux の公式ドキュメントは GitBook 形式なのですが、GitBook にするためのソースは全て GitHub で公開されています。これを以下の手順で処理して、翻訳していきます。

  1. まずは自分の GitHub アカウントを持つ。
  2. Redux ドキュメントの GitHub リポジトリから自分の GitHub へ Fork する。
  3. GitBook のアカウントと、自分の GitHub アカウントを連携させる。
  4. 自分の GitHub アカウント内の Fork した Redux ドキュメントのリポジトリを、GitBook 上で読み込む。
  5. GitBook のブラウザ・エディタで翻訳する。
  6. GitBook で Publish すると、GitBook 上のリポジトリにも、連携している自分の GitHub リポジトリにも自動的に反映される。

こうすると次のような利点があります。

  1. GitBook と GitHub が sync するので、どちらか一方を編集した際に、もう一方も変更される。
  2. GitBook のウェブ上のエディターを用いることで、GitBook で公開されるフォーマットとほぼ同じ形のまま、編集・翻訳できる。
  3. GitBook で Publish すると、その結果が GitHub にコミットされるので、GitHub で OSS に貢献している雰囲気が非常に出る。(活動ログに濃い緑色のマップが作成できる)

“Redux 公式ドキュメントのリポジトリ→ GitHub fork → GitBook の連携” の続きを読む

React v16.0 メジャーバージョンアップ

例によって勝手に翻訳

https://reactjs.org/blog/2017/09/26/react-v16.0.html

個人的な react 16 関連情報リスト

React v16.0

We’re excited to announce the release of React v16.0! Among the changes are some long-standing feature requests, including fragmentserror boundariesportals, support for custom DOM attributes, improved server-side rendering, and reduced file size.

React v16.oのリリースをお知らせできることに、胸が高鳴っています。今回の変更の中には、皆さんから長く要望いただいていた機能もあります。fragmentserror boundariesportals, custom DOM attributes のサポート, 改善された server-side rendering, そして reduced file size などです。

New render return types: fragments and strings

render メソッド内における return の新しい形式:fragment と string

You can now return an array of elements from a component’s render method. Like with other arrays, you’ll need to add a key to each element to avoid the key warning:

コンポーネントの render メソッド内で、要素の配列を return することが出来るようになりました。他の配列と同様に、各要素に key を与える必要があります。これにより key warning を避けることができます。

// list item を余計な要素で囲む必要はありません。

// key を与えることを忘れずに。

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

In the future, we’ll likely add a special fragment syntax to JSX that doesn’t require keys.

将来的には、JSXのための特別な fragment シンタックスを提供する予定です。このシンタックスにおいては、key は必要なくなります。

We’ve added support for returning strings, too:

また文字列の return にも対応しました。

//「 見てよお母さん。span で囲まなくてもいいんだ。

render() {
  return 'Look ma, no spans!';
}

See the full list of supported return types.

Better error handling

エラー・ハンドリングの改善

Previously, runtime errors during rendering could put React in a broken state, producing cryptic error messages and requiring a page refresh to recover. To address this problem, React 16 uses a more resilient error-handling strategy. By default, if an error is thrown inside a component’s render or lifecycle methods, the whole component tree is unmounted from the root. This prevents the display of corrupted data. However, it’s probably not the ideal user experience.

以前は、レンダリング時にランタイム・エラーが生じた場合、React は壊れた状態になってしまい、意味不明なエラー・メッセージを表示していました。そしてその状態を直すためにはページを再更新する必要がありました。 このような問題に対処するため、React 16 はより柔軟性のあるエラーハンドリング戦略を用いることにしました。初期設定では、エラーがコンポーネントの render メソッドやライフサイクル・メソッドの中で生じた場合、コンポーネント・ツリー全体が、ルートコンポーネントからアンマウントされるようになっています。これによって、壊れたデータが表示されることを防いでいます。しかし、おそらくこれは、理想的なユーザー体験とは言い難いものです。

Instead of unmounting the whole app every time there’s an error, you can use error boundaries. Error boundaries are special components that capture errors inside their subtree and display a fallback UI in its place. Think of error boundaries like try-catch statements, but for React components.

エラーが生じる度にアプリケーション全体をアンマウントするのではなく、代わりに「Error Boundaries」を用いることができます。「Error boundaries」は、特別なコンポーネントで、自身の下層にあるツリーで生じたエラーを捉えて、フォールバック UI を代わりに表示します。「Error boundaries」は、トライ/キャッチ文と同じようなものだと考えてもいいでしょう。ただし React コンポーネントのためのトライ/キャッチ文です。

For more details, check out our previous post on error handling in React 16.

詳細は previous post on error handling in React 16 を確認ください。

Portals

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

「portal」機能は、子要素を、親コンポーネントのDOMヒエラルキーの外側に存在するDOM node に対して、レンダリングする機能です。

render() {
  // React does *not* create a new div. It renders the children into `domNode`.
  // `domNode` is any valid DOM node, regardless of its location in the DOM.
  return ReactDOM.createPortal(
    this.props.children,
    domNode,
  );
}

See a full example in the documentation for portals.

(訳注: react は通常、自分の子要素の位置にコンポーネントをレンダリングするが、portal を用いると、その縛りから放たれて、どの DOM に対してもコンポーネントをレンダリングをできるようだ。具体的なユースケースとして、overflow: hidden されている親要素の中のコンポーネントから、モーダルウィンドウを生成したい場合があげられている。通常であれば、overflow: hidden されている要素の子要素として DOM がレンダリングされる以上、親要素の外にはみ出るような視覚表現を作り出すことができない。このような条件において、親要素の外側に DOM をレンダリングする必要が発生し、その場合に portal 機能が有用となる。)

Better server-side rendering

サーバーサイドレンダリングの改善

React 16 includes a completely rewritten server renderer. It’s really fast. It supports streaming, so you can start sending bytes to the client faster. And thanks to a new packaging strategy that compiles away process.env checks (Believe it or not, reading process.env in Node is really slow!), you no longer need to bundle React to get good server-rendering performance.

React 16 は、完全に新たに書き直された server render を用いています。これによって非常に早くなりました。この新しい server render は、ストリーミングをサポートしており、非常に早くクライアントへの情報送信を開始することができるようになりました。また  new packaging strategy のお陰で(これはprocess.env のチェックをコンパイルから取り除いています。信じられないかもしれませんが、Node の process.env は本当に遅いのです!)、サーバーレンダリングのパフォーマンスをよくするためにReact をバンドルする、ということが必要なくなりました。

Core team member Sasha Aickin wrote a great article describing React 16’s SSR improvements. According to Sasha’s synthetic benchmarks, server rendering in React 16 is roughly three times faster than React 15. “When comparing against React 15 with process.env compiled out, there’s about a 2.4x improvement in Node 4, about a 3x performance improvement in Node 6, and a full 3.8x improvement in the new Node 8.4 release. And if you compare against React 15 without compilation, React 16 has a full order of magnitude gain in SSR in the latest version of Node!” (As Sasha points out, please be aware that these numbers are based on synthetic benchmarks and may not reflect real-world performance.)

React 開発のコアメンバーである「Sasha Aickin」がRact 16 の SSR が大きく進歩したということについて記事を書いています。「great article describing React 16’s SSR improvements」 Sahsa のシンセティック・ベンチマークによればReact 16 のサーバーレンダリングは、ざっくりって React 15 の3倍は早いことがわかりました。「process.env をコンパイルした React15 と比較すると、node 4 では2.4倍の改善がされ、node 6 では3倍の、そして最新のnode 8.4 では3.8倍の改善がされました。そしてコンパイルなしの react 15 と比較するとすれば、最新バージョンの Node では、なんと一桁違う改善がされています!」(Sashaが指摘していることですが、この数字はシンセティック・ベンチマークによるもので、実際のパフオーマンスを、必ずしも反映するものではない点に注意してください。)

In addition, React 16 is better at hydrating server-rendered HTML once it reaches the client. It no longer requires the initial render to exactly match the result from the server. Instead, it will attempt to reuse as much of the existing DOM as possible. No more checksums! In general, we don’t recommend that you render different content on the client versus the server, but it can be useful in some cases (e.g. timestamps).

加えて、React 16 は hydrating server-rendered HTML を改善しています。(ただし一旦クライアントにリーチした場合のみですが) 最早、サーバーからの結果と完全にマッチさせるために最初のレンダリングをする、という必要がなくなりました。その代わりに、既に存在するDOMを最大限、再活用するようになりました。もうチェックサムは必要ありません!一般的に言って、クライアント側とサーバー側で異なるコンテンツをレンダリングすることは、おすすめしません。とはいえ有効なケースもあります。(例えばtimestampなど)

See the documentation for ReactDOMServer for more details.

Support for custom DOM attributes

カスタム DOM 属性のサポート

Instead of ignoring unrecognized HTML and SVG attributes, React will now pass them through to the DOM. This has the added benefit of allowing us to get rid of most of React’s attribute whitelist, resulting in reduced file sizes.

HTML と SVG の React が認識できない属性に関して、今まで React は無視をしてきましたが、React 16 ではそのまま DOM に渡すようになりました。これによって以前のReactのホワイト・リストを使わなくて良くなるので、結果としてファイルサイズが小さくなります。

Reduced file size

小さくなったファイルサイズ

Despite all these additions, React 16 is actually smaller compared to 15.6.1!

様々な機能追加にもかかわらず、React 16 は 15.6.1 よりもファイルサイズが小さくなりました!

  • react is 5.3 kb (2.2 kb gzipped), down from 20.7 kb (6.9 kb gzipped).
  • react-dom is 103.7 kb (32.6 kb gzipped), down from 141 kb (42.9 kb gzipped).
  • react + react-dom is 109 kb (34.8 kb gzipped), down from 161.7 kb (49.8 kb gzipped).

That amounts to a combined 32% size decrease compared to the previous version (30% post-gzip).

The size difference is partly attributable to a change in packaging. React now uses Rollup to create flat bundles for each of its different target formats, resulting in both size and runtime performance wins. The flat bundle format also means that React’s impact on bundle size is roughly consistent regardless of how you ship your app, whether it’s with Webpack, Browserify, the pre-built UMD bundles, or any other system.

サイスが小さくなった理由の一部は、packaging 方法の変更にあります。React は Rollup を用い、異なった対象のフォーマットへのフラットバンドルを作っています。結果としてサイズの点でもランタイム・パフォーマンスの点でも向上しました。フラットバンドルフォーマットであるということは同時に次のことも意味します。つまり、Webpack, Browserify, the pre-built UMD bundles, や他のどのシステムを用いてアプリケーションを最終的にバンドルするとしても、Reactのバンドルサイズは小さいままです。

MIT licensed

In case you missed it, React 16 is available under the MIT license. We’ve also published React 15.6.2 under MIT, for those who are unable to upgrade immediately.

React 16 は MIT ライセンスで運用されます。15.6.2 も同じく MIT ライセンスでした。

New core architecture

新しいコア・アーキテクチャ

React 16 is the first version of React built on top of a new core architecture, codenamed “Fiber.” You can read all about this project over on Facebook’s engineering blog. (Spoiler: we rewrote React!)

React 16 は新しいコアアーキテクチャである”Fiber”のもと構築された、最初のReact です。このプロジェクトの全貌については Facebook’s engineering blog の記事で知ることができます。

Fiber is responsible for most of the new features in React 16, like error boundaries and fragments. Over the next few releases, you can expect more new features as we begin to unlock the full potential of React.

“Fiber” こそが、React 16 の新機能の多くの立役者です。error boundaries や fragment といった新機能は Fiber によって成り立っています。次に続くいくつかのリリースでも、さらに多くの新機能を追加する予定です。React のポテンシャルを最大限引き出していきます。

Perhaps the most exciting area we’re working on is async rendering—a strategy for cooperatively scheduling rendering work by periodically yielding execution to the browser. The upshot is that, with async rendering, apps are more responsive because React avoids blocking the main thread.

おそらく一番エキサイティングな部分は「async rendering」でしょう。

This demo provides an early peek at the types of problems async rendering can solve:

 Follow
Andrew Clark @acdlite

Ever wonder what “async rendering” means? Here’s a demo of how to coordinate an async React tree with non-React work https://gist.github.com/acdlite/f31becd03e2f5feb9b4b22267a58bc1f 

Twitter Ads info and privacy

Tip: Pay attention to the spinning black square.

We think async rendering is a big deal, and represents the future of React. To make migration to v16.0 as smooth as possible, we’re not enabling any async features yet, but we’re excited to start rolling them out in the coming months. Stay tuned!

Installation

React v16.0.0 is available on the npm registry.

React v16.0.0 は npm レジストリ上で手に入れることができます。

To install React 16 with Yarn, run:

Yarn を用いて React 16 をインストールするには、次のコマンドを実行してください。

yarn add react@^16.0.0 react-dom@^16.0.0

To install React 16 with npm, run:

npm を用いて React 16 をインストールするには、次のコマンドを実行してください。 

npm install --save react@^16.0.0 react-dom@^16.0.0

We also provide UMD builds of React via a CDN:

また、React の UMD ビルドを CDN を通じて提供しています。

<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

Refer to the documentation for detailed installation instructions.

Upgrading

Although React 16 includes significant internal changes, in terms of upgrading, you can think of this like any other major React release. We’ve been serving React 16 to Facebook and Messenger.com users since earlier this year, and we released several beta and release candidate versions to flush out additional issues. With minor exceptions, if your app runs in 15.6 without any warnings, it should work in 16.

React 16 は莫大な内部変更が加えられましたが、アップグレードという観点からいえば、他の React メジャーバージョンアップのリリースと変わりません。我々は既に今年の初めには React 16 を Facebook や Messenger.com のサービスに使用しており、幾つかのベータ版と候補バージョンを出して、機能を追加してきました。いくつかの細かな例外を除けば、あなたのアプリケーションが 15.6 上で warning なしに動いているのであれば、基本的に 16 上でも動作します。

New deprecations

Hydrating a server-rendered container now has an explicit API. If you’re reviving server-rendered HTML, use ReactDOM.hydrate instead of ReactDOM.render. Keep using ReactDOM.render if you’re just doing client-side rendering.

「Hydrating a server-rendered container」に関しては、新たに明示的な API を持つことになりました。「reviving server-rendered HTML」しているのであれば、ReactDOM.render ではなく ReactDOM.hydrate を使用してください。単にクライアントサイドレンダリングをしている場合には、いつもどおりReactDOM.render を使用してください。

React Addons

As previously announced, we’ve discontinued support for React Addons. We expect the latest version of each addon (except react-addons-perf; see below) to work for the foreseeable future, but we won’t publish additional updates.

既に発表した通り、React Addons のサポートを打ち切りました。それぞれのaddon の最終バージョンは、しばらく問題なく動くはずですが、しかし新たな更新をする予定はありません。

Refer to the previous announcement for suggestions on how to migrate.

react-addons-perf no longer works at all in React 16. It’s likely that we’ll release a new version of this tool in the future. In the meantime, you can use your browser’s performance tools to profile React components.

react-addons-perfは React 16 では動きません。おそらく新しいこういったツールを将来発表するはずです。しばらくのあいだは、ブラウザのパフォーマンスツールを使ってReact コンポーネントの捜査を行ってください。 (use your browser’s performance tools to profile React components.)

Breaking changes

破壊的変更

React 16 includes a number of small breaking changes. These only affect uncommon use cases and we don’t expect them to break most apps.

React 16 はかなりの数の破壊的変更が加えられました。これらが影響をあたえるのはかなり特殊なケースで運用されているアプリケーションに限られており、ほとんどのアプリケーションにおいて、動かなくなることはないと予想しています。

  • React 15 had limited, undocumented support for error boundaries using unstable_handleError. This method has been renamed to componentDidCatch. You can use a codemod to automatically migrate to the new API.
  • ReactDOM.render and ReactDOM.unstable_renderIntoContainer now return null if called from inside a lifecycle method. To work around this, you can use portals or refs.
  • setState:
    • Calling setState with null no longer triggers an update. This allows you to decide in an updater function if you want to re-render.
    • Calling setState directly in render always causes an update. This was not previously the case. Regardless, you should not be calling setState from render.
    • setState callbacks (second argument) now fire immediately after componentDidMount / componentDidUpdate instead of after all components have rendered.
  • When replacing <A /> with <B />B.componentWillMount now always happens beforeA.componentWillUnmount. Previously, A.componentWillUnmount could fire first in some cases.
  • Previously, changing the ref to a component would always detach the ref before that component’s render is called. Now, we change the ref later, when applying the changes to the DOM.
  • It is not safe to re-render into a container that was modified by something other than React. This worked previously in some cases but was never supported. We now emit a warning in this case. Instead you should clean up your component trees using ReactDOM.unmountComponentAtNode. See this example.
  • componentDidUpdate lifecycle no longer receives prevContext param. (See #8631)
  • Shallow renderer no longer calls componentDidUpdate because DOM refs are not available. This also makes it consistent with componentDidMount (which does not get called in previous versions either).
  • Shallow renderer does not implement unstable_batchedUpdates anymore.
  • ReactDOM.unstable_batchedUpdates now only takes one extra argument after the callback.

Packaging

  • There is no react/lib/* and react-dom/lib/* anymore. Even in CommonJS environments, React and ReactDOM are precompiled to single files (“flat bundles”). If you previously relied on undocumented React internals, and they don’t work anymore, let us know about your specific case in a new issue, and we’ll try to figure out a migration strategy for you.
  • There is no react-with-addons.js build anymore. All compatible addons are published separately on npm, and have single-file browser versions if you need them.
  • The deprecations introduced in 15.x have been removed from the core package. React.createClass is now available as create-react-classReact.PropTypes as prop-typesReact.DOM as react-dom-factoriesreact-addons-test-utils as react-dom/test-utils, and shallow renderer as react-test-renderer/shallow. See 15.5.0 and 15.6.0 blog posts for instructions on migrating code and automated codemods.
  • The names and paths to the single-file browser builds have changed to emphasize the difference between development and production builds. For example:
    • react/dist/react.js → react/umd/react.development.js
    • react/dist/react.min.js → react/umd/react.production.min.js
    • react-dom/dist/react-dom.js → react-dom/umd/react-dom.development.js
    • react-dom/dist/react-dom.min.js → react-dom/umd/react-dom.production.min.js

JavaScript Environment Requirements

React 16 depends on the collection types Map and Set. If you support older browsers and devices which may not yet provide these natively (e.g. IE < 11), consider including a global polyfill in your bundled application, such as core-js or babel-polyfill.

React 16 は Map や Set に依存しています。そのためこれらをサポートしてない古いブラウザにおいては(例えばIE11未満)、グローバルな polyfill をバンドルアプリケーションに含めることを検討してください。例えば core-js や babel-polyfill などを用いてください。

A polyfilled environment for React 16 using core-js to support older browsers might look like:

次のソースは、古いブラウザでも react 16 が動くようにするために、core-js を用いて React 16 のための polyfill が適用された環境の例です。

import 'core-js/es6/map';
import 'core-js/es6/set';

import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);

React also depends on requestAnimationFrame (even in test environments). A simple shim for test environments would be:

React は  requestAnimationFrame にも依存しています。(テスト環境においても依存してます) テスト環境用のシンプルな shim は以下のようになります。

global.requestAnimationFrame = function(callback) {
  setTimeout(callback, 0);
};

Acknowledgments

As always, this release would not have been possible without our open source contributors. Thanks to everyone who filed bugs, opened PRs, responded to issues, wrote documentation, and more!

Special thanks to our core contributors, especially for their heroic efforts over the past few weeks during the prerelease cycle: Brandon Dail, Jason Quense, Nathan Hunzaker, and Sasha Aickin.

Edit this page

React / Functional Component の書き方のバリエーション

(インデントが崩れてしまうのは自分が使っているwordpressプラグインの仕様のようです…困った)

https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc

//1.基本形
//もしこの例の用に、JSXを返すだけであれば3.省略形を使ってもいい
import React from 'react';

const App = ()=> {
  return (
    

<div>This is App component</div>


  );
};

export default App;

//2.propsを受け取る場合 また関数や変数を持たせる場合
//classで書いた場合と異なり、thisの扱いをしなくていいので、楽
//stateをもたせる必要がなければこれでいい
import React from "react";

const App = ({ name }) => {
  const mrName = "Mr. " + name;
  const alertName = name => {
    alert(name);
  };
  return (
    

<div>
      

<div>
        this is Component {mrName}
      </div>


      <button onClick={() => {
          alertName(name);
        }}
      />
    </div>


  );
};

export default App;
//3.省略形
//単にjsxを返すだけであれば、これが一番シンプルな記述
import React from 'react';

const App = ()=> (
  

<div>This is App component</div>


);

export default App;

日本語訳: Presentational and Container Components

勝手に翻訳シリーズ

元の記事

https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0

Presentational and Container Components

Bismuth
There’s a simple pattern I find immensely useful when writing React applications. If you’ve been doing React for a while, you have probably already discovered it. This article explains it well, but I want to add a few more points.
とても有益でシンプルなパターンを、Reactを書いているときに見つけました。もちろんあなたもReactをある程度書いたことがあれば、多分同じようなことを既に発見されていることでしょう。Thisこの記事も同じことについて説明しています。ですが、さらにいくつか新しいことを紹介できるとおもいます。
You’ll find your components much easier to reuse and reason about if you divide them into two categories. I call them Container and Presentational components* but I also heard Fat and SkinnySmart and Dumb, Stateful and PureScreens and Components, etc. These all are not exactly the same, but the core idea is similar.

ご存知だと思いますが、コンポーネントをうまく再利用するためには、そしてうまく整理するためには、コンポーネントを2種類に切り分けると良いのです。その二つを私はContainer ComponentとPresentational Componentと名付けることにしました。ですが人によってはFatとSkinny、SmartとDumb、StatefulとPure、ScreensとComponentsと、様々な呼び方をしています。これらは全てが完全に同じものではありませんが、中心的な役割は同じです。

My presentational components:

私がPresentationalと名付けたコンポーネントの特徴は以下の通りです。

  • Are concerned with how things look.
  • どのような見た目になるか、ということと関連づいている
  • May contain both presentational and container components** inside, and usually have some DOM markup and styles of their own.
  • PresentatinalコンポーネントとContainerコンポーネントの両方を内部に持つことができ、たいていの場合は自分自身のためのDOMマークアップとスタイルを持つ。
  • Often allow containment via this.props.children.
  • たいていの場合は、コンテンツをthis.props.childrenを用いて保持している。(訳注:公式参照 コンポーネントの<Component>ここ<Component>ここの部分入れらたものがthis.props.childrenで参照できる部分。通常、これは自動的にレンダリング時に参照され、内部で保持され、表示される。)
  • Have no dependencies on the rest of the app, such as Flux actions or stores.
  • アプリケーションの他の部分に対して依存している部分が一切ない。例えばFluxのactionやstoreに依存している部分がない。
  • Don’t specify how the data is loaded or mutated.
  • dataがどのようにロードされるか、もしくは変更されるか、といったことは定義しない。
  • Receive data and callbacks exclusively via props.
  • dataやコールバックは外部からprops経由で受け取る。
  • Rarely have their own state (when they do, it’s UI state rather than data).
  • 独自の状態を保つことは基本的にはない。(あるとすれば、UIの状態を持つ場合であってDateではない。)
  • Are written as functional components unless they need state, lifecycle hooks, or performance optimizations.
  • Functional コンポーネントとしてかかれる。状態やライフサイクルフック、パフォーマンス調整が必要とされない限りは。
  • Examples: Page, Sidebar, Story, UserInfo, List.
  • 例としては、Page, Sidebar, Story, UserInfo, Listなどがあげられる。

My container components:

私がContainerと名付けたコンポーネントの特徴は以下の通りです。

  • Are concerned with how things work.
  • どのように機能するか、ということと結びついてる。
  • May contain both presentational and container components** inside but usually don’t have any DOM markup of their own except for some wrapping divs, and never have any styles.
  • PresentatinalコンポーネントとContainerコンポーネントの両方を内部に持つことができるが、たいていの場合は自分自身のためのDOMマークアップとスタイルを「持たない」。
  • Provide the data and behavior to presentational or other container components.
  • データと挙動を、Presentationalコンポーネントや、他のContainerコンポーネントに対して提供する。
  • Call Flux actions and provide these as callbacks to the presentational components.
  • Fluxのアクションをcallしたり、アクションをコールバックとしてPresentatinalコンポーネンへ提供する。
  • Are often stateful, as they tend to serve as data sources.
  • たいていの場合は状態を持ち、データの源としての役割を担う。
  • Are usually generated using higher order components such as connect()from React Redux, createContainer() from Relay, or Container.create() from Flux Utils, rather than written by hand.
  • higher order componentを用いることで生成される。例えばReact Reduxのconnect()やRelayのcreateContainer()やFlux UtilsのContainerCreate()である。
  • Examples: UserPage, FollowersSidebar, StoryContainer, FollowedUserList.

I put them in different folders to make this distinction clear.

私はこの二つのコンポーネントを、異なるフォルダーに配置することで、明確に区別することにしています。

(訳注:ということは、Reduxのconnect()を使う層は、基本的にContainer Component。connectはなぜ使うかといえば、state,reducer,actionとpresentationalコンポーネントを、Containerコンポーネント内で結びつけるため。presentationalコンポーネントとactionをロードして、connectでstate,dispatchと結びつける。するとpresentationalコンポーネントにstate,dispatchが渡されるので、presentationalコンポーネントがそれを使えるようになる。connectで結びつけて作った新しい高次階層コンポーネントをexportし、これを他のコンポーネントから呼び出して使う。)

Benefits of This Approach

このアプローチの利点

  • Better separation of concerns. You understand your app and your UI better by writing components this way.
  • 役割の分割をうまくできる。コンポーネントをこう書くことで、アプリケーションとUIがどうなっているのか、より理解しやすくなる。
  • Better reusability. You can use the same presentational component with completely different state sources, and turn those into separate container components that can be further reused.
  • 使い回しが効く。Presentationalコンポーネントを全く異なるStateを持つ状況において使用することができる。また異なるContainerコンポーネントの中で使用することができる。
  • Presentational components are essentially your app’s “palette”. You can put them on a single page and let the designer tweak all their variations without touching the app’s logic. You can run screenshot regression tests on that page.
  • Presentatinalコンポーネントは、本質的にはアプリケーションの「パレット」である。ページのどこにでも配置することができ、デザイナーがアプリのロジックに触ることなく変更することができる。
  • This forces you to extract “layout components” such as Sidebar, Page, ContextMenu and use this.props.children instead of duplicating the same markup and layout in several container components.
  • こうすることで「layout Component」を強制的に取り除くことになるので、同じマークアップやレイアウトを様々なContainerコンポーネントになんども複製する必要がなくなる。this.props.childrenを使えばいい。

Remember, components don’t have to emit DOM. They only need to provide composition boundaries between UI concerns.

コンポーネントは必ずしもDOMを出力する必要はない、という点に注意してください。第一の役割は、コンポジションにおける境界を定義することにあります。

Take advantage of that.

どの段階でContainerを導入すべきか

When to Introduce Containers?

I suggest you to start building your app with just presentational components first. Eventually you’ll realize that you are passing too many props down the intermediate components. When you notice that some components don’t use the props they receive but merely forward them down and you have to rewire all those intermediate components any time the children need more data, it’s a good time to introduce some container components. This way you can get the data and the behavior props to the leaf components without burdening the unrelated components in the middle of the tree.

まずはPresentationalコンポーネントだけでAppを書き始めることをお勧めします。そうしていくと、最終的には、あまりに多くのpropsを中間層のコンポーネントに渡している、と感じることにはなると思います。propsを受け取ってはいるものの、用いておらず、単にさらに下部のコンポーネントへと渡しているだけのコンポーネントがあるような状況が生まれた場合が、Containerコンポーネントを導入するのに最適な段階でしょう。そうすれば、データや挙動のためのpropsを各コンポーネントに与えるために、関係のないコンポーネントを中間層に挟む必要がなくなります。

This is an ongoing process of refactoring so don’t try to get it right the first time. As you experiment with this pattern, you will develop an intuitive sense for when it’s time to extract some containers, just like you know when it’s time to extract a function. My free Redux Egghead series might help you with that too!

これはリファクタリンの際に継続的におこなうことなので、最初から行う必要はありません。このパターンで書く際に経験していることだと思いますが、いつコンテイナーを導入するのかということを感じ取るセンスを育む必要があります。これはちょうど、どの段階でFunctionにまとめるべきなのかを判断するセンスと似ています。 free Redux Egghead series も参考になるはず!

他の違い

Other Dichotomies

It’s important that you understand that the distinction between the presentational components and the containers is not a technical one. Rather, it is a distinction in their purpose.

presentationalコンポーネントとcontainerコンポーネントの違いは、技術的なものというよりは、その目的による、という点を理解することが重要です。

By contrast, here are a few related (but different!) technical distinctions:

  • Stateful and Stateless. Some components use React setState() method and some don’t. While container components tend to be stateful and presentational components tend to be stateless, this is not a hard rule. Presentational components can be stateful, and containers can be stateless too.
  • Stateful and Stateless.  ReactのsetState()を使うコンポーネントもあれば、使わないコンポーネントもあります。ContainerコンポーネントはStateを持つ傾向にあり、Presentationalコンポーネントがstateを持たない傾向にありますが、とはいえこれは厳密なルールではありません。Presentationalコンポーネントがstateを持つこともありますし、ContainerコンポーネントがStateを持たないこともあります。
  • Classes and Functions. Since React 0.14, components can be declared both as classes and as functions. Functional components are simpler to define but they lack certain features currently available only to class components. Some of these restrictions may go away in the future but they exist today. Because functional components are easier to understand, I suggest you to use them unless you need state, lifecycle hooks, or performance optimizations, which are only available to the class components at this time.
  • Classes and Functions. React 0.14から、コンポーネントはクラスとしてもファンクションとしても宣言できるようになりました。ファンクショナルコンポーネントは宣言がよりシンプルですが、クラスコンポーネントにしかない機能を持っていません。そういった制限が将来撤廃されるかもしれませんが、今のところは存在します。ファンクショナルコンポーネントは把握するのが簡単ですので、ステイト/ライフサイクルフック/パフォーマンスの調整といったクラスコンポーネントだけにしかない機能が必要でない場合には、ファンクショナルコンポーネントを使うことを推奨します。
  • Pure and Impure. People say that a component is pure if it is guaranteed to return the same result given the same props and state. Pure components can be defined both as classes and functions, and can be both stateful and stateless. Another important aspect of pure components is that they don’t rely on deep mutations in props or state, so their rendering performance can be optimized by a shallow comparison in their shouldComponentUpdate() hook. Currently only classes can define shouldComponentUpdate() but that may change in the future.
  • Pure and Impure. コンポーネントのうち、同じpropsと状態を与えれば、同じ結果を返すものを、Pureコンポーネント、と言ったりします。ピュアコンポーネントは、クラスでもファンクションでもどちらでも定義することができます。またステイトを持つことも持たないこともできます。(残りの部分わからず)

Both presentational components and containers can fall into either of those buckets. In my experience, presentational components tend to be stateless pure functions, and containers tend to be stateful pure classes. However this is not a rule but an observation, and I’ve seen the exact opposite cases that made sense in specific circumstances.

PresentationalコンポーネントもContainerコンポーネントも、そうではないもう一方のコンポーネントになる可能性が常にあります。私の経験では、Presentatinalコンポーネントはstatelessなピュアファンクションであり、Containerコンポーネントはstateを持つピュアクラスであることが多いようです。とはいえこれはルールではなくて、あくまでもそういうことが多いというだけなので、過去には全くの反対のケースで、しかも合理的、という状況もありました。

Don’t take the presentational and container component separation as a dogma. Sometimes it doesn’t matter or it’s hard to draw the line. If you feel unsure about whether a specific component should be presentational or a container, it might be too early to decide. Don’t sweat it!

PresentationalコンポーネントとContainerコンポーネントの区別を、教義のように考えないようにしてください。時にはそんなことを考える必要がない時もありますし、区別をすることが難しい場合もあります。どちらにすべきか確信が持てない場合には、それを決断するにはまだ早いのかもしれません。そんなことは気にしないで!

Example

This gist by Michael Chan pretty much nails it.

Further Reading

react-reduxの使い方まとめ

React

React そのものは次の記事も参照。(React 公式よりももっと低レベルなところから始める、React チュートリアル, React チュートリアル 日本語翻訳) React は State を元にバーチャルDOMを作成し、バーチャルDOMを元にDOMを生成するシステムを担うライブラリ。state の更新があった場合、その差分だけを DOM に反映することができ、パフォーマンスが良い。つまり、PC への負担が少ない。React を用いる利点のうち、一番大きなものは、状態 state と view 実際の見た目をどうするか、という「二つの問題を完全に切り分ける」ことができる。つまり、state をどう変化させるか、という問題と、state を DOMにどう反映させれるか、の2つを完全に切り分けて実装できる。

React Component

React はコンポーネントと呼ばれる最小単位を、積み重ねることでバーチャルDOM全体の構成を行う。具体的には、HTMLに直接紐付けられたトップのコンポーネントの中に、さらにコンポーネントを配置し、またさらにその下にコンポーネントを配置していくことができる。入れ子状に。(マトリョーシカのように一つのコンポーネントの中に、一つのコンポーネントしか配置できないわけではない。ある階層のコンポーネントには、複数の下位コンポーネントを配置することができる。)

state を持つコンポーネントと持たないコンポーネント

React コンポーネントは、コンポーネント自身が状態 state を持つものと(一般的にES6のクラス構文で書かれ、extended React.componentし、コンストラクタ内でsuper(props)によってReact.componentを継承し、this.stateに状態をオブジェクトとして持たせる / 公式ref  もしくはこれ 参照)ともたない functional component がある。

持つコンポーネントの場合、stateはprivateであり、つまり状態はコンポーネントの外からアクセスできない。アクセスできるようにするためには、react の機能だけで実装する場合には、stateを下位のコンポーネントへpropsとして渡す方法がある。(反対に上位のコンポーネントに渡すことも原理的には可能だが、上下二方向にデータが流れると設計が破綻することが多く、そのため基本的には下位コンポーネントへstateを流していく。)

原理的にはすべてのコンポーネントにstateを持たせることができるが、reduxと連携する場合には、stateはすべてreduxによって管理するため、コンポーネントにstateを持たせず、すべてのコンポーネントをfunctional componentで書く。(ただし、UI用のstateを持たせることはある)

state の更新と取得

stateの更新は、this.state.setState(オブジェクト)によって行われ、その際に新しいstate用のオブジェクトを与えれば良い。stateの取得は、this.state.value によって可能である

Redux

Redux 公式ドキュメント 日本語に一部翻訳

Redux は state 管理のためのライブラリで、必ずしもReactと連携する必要はなく、単体で動作するが(公式チュートリアル参照)、React と共に用いられることが多いのは事実である。ここでは基本的にReactと連携することを前提に進める。また、当然だが React の状態管理は必ずしもReduxを用いる必要はなく、前述したreactコンポーネントのstateを用いることが第一の方法である。

Redux によって、React を用いたアプリケーションの状態を管理させる第一の利点は、データフローの設計と構造のベストプラクティスのうちの一つを、同時に取り込むことができる点にある。つまりどのようにstateを更新するのかという仕組みと、それを実装するための手段を、Reduxによって同時に取り込むことができる。Redux は具体的には、stateを1つの単なるオブジェクトで管理し、その更新にはreducerというこれまた単なる関数を用いる。Reducer ファンクションに対して二つの引数、現在の状態と、その変更に必要なパラメーターをactionを渡し、その二つの引数を元に更新されたstateを生成し、これをreturnする。

returnしたstateがどのように、更新されるか。それはstore = createStore(reducer)によってreducerを紐付けて、state管理用のstoreという変数を作ることからはじまる。これによって、reducerのreturnしたstateが、storeに返され、stateが更新される。

Redux と Flux の関係

Reduxは、stateの管理とその更新のシステムを書く方法を、単一に定義している。そのシステムは基本的にFluxに従っている。Fluxは状態管理の設計思想である。そのためライブラリではない。(ただしfluxというそのためのライブラリもある) つまりFluxが概念としては一番大きいもので、ReduxはFluxに基づいた実装のための方法の一つを担うライブラリである。

Redux は、そのシステムに則って書けば、結果的にFluxになるので、初学者にはむしろ易しい。Reduxを書くことによって、Fluxの概念を理解することが容易になるのではないか。またReduxは公式チュートリアルが非常に丁寧であり、その点もFluxを理解するためによい。

またReduxはstateを一箇所だけで管理するために、実際の業務においては、これでは問題が起きるシーンがある。そういった場合には、Fluxに則っり、しかしReduxを使わずに、自分でstateの管理を実装する必要が出てくる。そのため、単にReduxの「書き方」のように覚えてしまうのではなく、reactとstateの管理、変更について深い理解をすることが必要になると思われる。

Reduxによるstateの作成

reduxからcreateStoreを引っ張ってきて、createStoreでreducerを紐付けることで作ったstoreでstateを管理する。

createStoreの準備

import { createStore } from 'redux';

storeの作成。reducerと紐付ける。(reducerはステイトの初期値、変更、といった管理業務を一手に引き受けている)

let store = createStore(counter);

providerによってreactのコンポーネントとstoreを結びつける

react-reduxからproviderを引っ張ってきて、providerでreactコンポーネントの一番上の層(一番上でなくてもいいが、そのコンポーネント以下から参照可能になる)とstoreを紐付けることで、その下のコンポーネントにおいてconnectを使うことが可能になる。(connectの役割は、storeとあるコンポーネントを紐付けて、そのコンポーネント内でstoreの参照ができるようにすること。)

Providerを引っ張ってくる。

import { Provider } from 'react-redux';

コンポーネントの最上部にstoreをProviderによって紐付ける。ここではTestコンポーネント以下にstoreを紐付けるために、TestコンポーネントをProviderでラップした上で、それにstore={ store } というpropsを与えることで実現している。

const AppRoot = () => (
    <Provider store={ store }>
        <Test />
    </Provider>
);

ただしこれだけですべてのコンポーネントからstoreが参照できるわけではない。次の手順を加える。

providerによって紐付けられたstoreを、各コンポーネント内で参照できるように、connectによってコンポーネントとstoreの紐づけを行う

react-reduxからconnectを引っ張ってくる

import { connect } from 'react-redux';

仮に以下のようなTestというコンポーネントを用意しており、これとstoreを結びつけるとする。

const Test = ({dispatch, num}) => (
    <div>
        {num}
        <button onClick={()=>{dispatch({ type: 'INCREMENT' })}}>+</button>
        <button onClick={()=>{dispatch({ type: 'DECREMENT' })}}>-</button>
        <Test2/>
    </div>
);

まずmapStateToPropsという中間的な役割を担う関数で、storeのstateのうち、どのstateを必要とするか、定義する。ここではstate全体を引っ張ってきて、numという値として渡すことにしている。

Testコンポーネントをexport defaultで書き出す際に、connect(関連づけるstate)(関連づけるTestコンポーネント)という記述で、conncetされたTestコンポーネントを書き出している。

function mapStateToProps(state) {
    return { num: state }
}

export default connect(mapStateToProps)(Test)

紐付けられたコンポーネントにおいては、以下のように、dispatchがグローバルな変数として使うことができる。また{num}のようにmapStateToPropsで紐付けたstateを参照できる。

const Test = ({dispatch, num}) => (
    <div>
        {num}
        <button onClick={()=>{dispatch({ type: 'INCREMENT' })}}>+</button>
        <button onClick={()=>{dispatch({ type: 'DECREMENT' })}}>-</button>
        <Test2/>
    </div>
);

手順まとめ

  1. createStoreでstoreを作る。storeでstateを管理する。createStoreをする際に、reducerを紐付ける。reducerはstateの更新を担当するもの。storeにreducerが紐付いているので、store.dispatch({action:content})でstateを変更できる。
  2. providerを用いてreactコンポーネントの階層の一番上にstoreをprospsとして渡すことで、その下の階層でconnectを使うことができる。そのためにはreactコンポーネント階層の一番上のコンポーネントをProviderコンポーネントでラップし、Providerコンポーネントに、storeという名前で{ store }  を渡す。
  3. Providerコンポーネントによって渡されたstoreを、様々な階層の位置にあるコンポーネントから参照するためにはconnect()を用いる。コンポーネントを出力するexport defalut 以降に export defalut connect(propsを紐付ける中間関数)(紐付けるコンポーネント)とする。propsを紐付ける中間関数は、storeに保持されているstateのうち、必要なものだけを選んで使用するためのもの。

reducer や action の効率的な取りまとめ

ReducerをcombineReducersでsplitする

https://codesandbox.io/s/kR1jXvD7X

次のようなstateをreduxで管理する場合、counterとtext、それぞれのpropertyのvalueに対して、1つのreducerをわり当てる方が、全体をたった一つのreducerで管理するよりも、関心を分離できるので、開発に有利。

state = {counter:0,text:”text”}

そのためには、reducersフォルダの中にindex.jsを作り、ここで全てのreducerをimportし、それをcombineReducerでまとめる。そしてこれをimport reducer from ‘./reducers’として、reducerをcreateStore(reducer)で紐付ける。

reduxのcombineReducerを用いる。

// reducers/index.js
//ここで全てのreducerをimportする
import counter from './counter'
import text from './text'

//複数reducerをimportした場合には、combineReducerでまとめる
 import { combineReducers } from 'redux'

const main = combineReducers({
  counter,
  text
});

export default main;

&lt;strong&gt;//こうすると、stateが、
//{counter: 内容, text:内容}というオブジェクトになる。
//合体している。
&lt;/strong&gt;

importの対象をディレクトリにすると、その直下にあるindex.jsを読み込むことになる。結果として上記コードのmainをimportすることになる。そしてそれをstoreと紐付ける。

import React from 'react';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import Test from './Test';
&lt;strong&gt;//reducerが複数入っているディレクトリ。
//ディレクトリを指定するだけで、そのなかのindex.jsでexportされているものが読み込まれる
import reducer from './reducers';
&lt;/strong&gt;

//redux の createStore で Reducer と結びつける
const store = createStore(reducer);

const AppRoot = () =&gt; (
    &lt;Provider store={ store }&gt;
        &lt;Test /&gt;
    &lt;/Provider&gt;
);

store.subscribe(() =&gt;
    console.log(store.getState())
);

export default AppRoot;

Actionを作成するaction creator

一つの方法として、actionsディレクトリ内にindex.jsというファイルを作り、その中でAction Creatorを作成し、作成したものをexportしておく。それをContainer層で読み込み、 同様にContainer層で読み込まれたComponentと結びつけるために、mapDispatchToProps内dispatchを呼び出す際に使用する。

疑問 ToDoListというcomponentを引っ張ってきて、Container層で各種要素をconnectしたものをVisualTodoListとしてexportしている。

 

 

Redux video チュートリアル

videoチュートリアル本体

https://egghead.io/courses/getting-started-with-redux

完成系のgitリポジトリ

https://github.com/sadams/todo-redux-react-webpack

ダイジェストが書かれたノート

https://github.com/tayiorbeii/egghead.io_redux_course_notes

だいたいわかったら12からやればいい。

14からが結構難しい。reducerを合体させる。しかもstateがオブジュエクトの場合。todoAppという上位のリデューサーに統合している。これはstateがなんとオブジェクト。

17リアクト連携

26 Redux: storeをReact Redux の<provider>を用いて下層へと渡していく

Redux: Passing the Store Down with <Provider> from React Redux

https://egghead.io/lessons/javascript-redux-passing-the-store-down-with-provider-from-react-redux

In the previous session, we implemented the provider component that uses the react advanced context feature to make this tool from the props available to every component in our rev.

一つ前のレッスンにおいて、私たちは provider コンポーネントを実装しました。これは react の アドヴァンスドな contect 機能を用いて、props をどのコンポーネントからも利用できるようにするものでした。

If we pass it through the provider, we can read it in any other component from the context, which is really convenient for the container components. In fact, this is so convenient that you don’t need to actually write the provider yourself, because it is included in a special library called React-Redux.

provider を通して値を渡すことで、どのコンポーネントからも context を通じて値を取得できるので、コンテナーコンポーネントにとってこれは非常に便利なことです。でも実は、 provider を自分自身で書く必要もありません。React-Redux という別のライブラリーにこの機能があるからです。

Note that it is not the same as Redux. This is a different library. These are react bindings to the Redux library. You can import the provider by destructuring the react-redux global object in JS bin, or if you use Babel, and something like NPM, you can import provider with the braces, because it’s a named expert from React-Redux package. Or if you write ES5 code, you can write var provider equals require react redux, or react redux global.provider.

注意して欲しいのですが、これは Redux とは別のライブラリーです。React-Redux は react とRedux をつなぐ効能を提供します。これを使うためには react-react global object を分解して provider を import するか(const Provider = ReactRedux;)、もしくは Babel と npm などを使っているのであれば、provider を{} を使ってインポートしましょう。(import {Provider} = ‘react-redux’;) このようにかけるのは、React-Redux の中でそのように名前が定義されているからです。さらに他の方法としてES5で書いているのであれば、var Provider = require(‘react-redux’).Provider; とします。

Just like the provider we wrote before, the provider that comes with react-redux exposes this store you passed through. There’s a prop on the context so the components can specify the context types, and then use this context store to subscribe to the store updates and dispatch actions.

前のレッスンで我々が書いた providerと同じように、react-redux によって提供される provider も redux の store を露出させます。(わからない。おそらく前のレッスンでcontext等を理解する必要がある。⇨) There’s a prop on the context so the components can specify the context types, and then use this context store to subscribe to the store updates and dispatch actions. とにかく結論としては、store のアップデートとディスパッチをreactに紐付ける。その際に context が関係してくる。

27 Redux: React-Reduxのconnect()を用いたコンテナを生成する

Redux: Generating Containers with connect() from React Redux (VisibleTodoList)

In the previous lesson, I added React Redux bindings to the project and I used a provider component from React Redux to pass this chore down the context so that the container components can re-dischore from the context and subscribe to these changes. All container components are very similar.

ここまでのレッスンにおいて、React Redux の bindings をプロジェクトに加えたので、

They need to re-render when the store state changes, they need to unsubscribe from the straw when they amount and they take the current state of the Redux store and use it to render the presentational components with some props that they calculate from the state of this chore, and they also need to specify the context stripes to get this chore from the context.

?外したりつけたり?

I’m going to write this component in a different way now. I’ll declare a function called “MapsStateToProps” which takes the redux store state and returns the props that I need to parse through the presentation to do this component, to render it with the current state.

ですが今回は少し違った方法でコンポーネントを書いていきます。まずは MapsStateToProps という名前の関数を宣言します。これはredux の state を受け取ってprops を return するためのものです。そしてこの props は presantation で分解されコンポーネントへ渡され、現在の状態によってレンダーされます。

In this case, there is a single prop called ToDo. I copy-paste this expression to the MapStateToProps function. It returns the props that depend on the current state of the redux store. In this case, this is just the ToDo list prop.

components/TodoList.jsx の TodoListというコンポーネントはToDOという名前のpropだけを用いていますね。これをコピペして、MapStateToPropsに加えます。そうすることで 現在のredux storeの状態に基づいたpropsを返し、Todoという名前で使うことができるようになります。(ただしの後の作業、connect()を行った後に。)

const mapStateToProps = (
  state
) => {
  return {
    todos: getVisibleTodos(
      state.todos,
      state.visibilityFilter
    )
  };
};

I’m creating another function that a core map dispatched the props. It accepts the dispatch method from this chore as the only argument and returns the props that should be parsed through the list component and that depend on the dispatch method.

The only prop that uses chore dispatch is called OnToDo click. Some copy-paste onto the click, into map dispatch the props. Now that I don’t have the reference to this chore here anymore. Instead, I’m changing it to use the dispatch, which is provided as an argument to map dispatch the props.

I will add some punctuation to make it appear easier on my eyes. OnToDo click ease of function that accepts the ID of the ToDo, and dispatches an action. Now, I’ve got two different functions.

The first one maps the redux chore state to the props of the ToDo list component that are related to the data from the redux chore. The second function maps the dispatch method of this chore to the callback props of ToDo list component. It specifies the behavior which callback prop dispatches which action.

To gather this, your function has described a container component so well that instead of writing it, I can generate it by using the connect function provided by react redux library. If you use Babble and NPM, you will likely input it like this instead. Don’t forget the curly braces.

Now, instead of declaring a class, I’m going to declare a variable. I will call the connect method to obtain it. I’m parsing MapsStateToProp as the first argument and MapDispatchTheProps as the second argument. Notice that this is a correct function, so I have to call it once again. This time, I parse the presentational component that I wanted to wrap and parse the props to you.

The connect function will generate the component, just like the one I previously wrote by hand. I don’t need to write the code to subscribe to this chore or to specify the context stripes, because the connect function takes care of that.

Now, let’s recap how to generate the container component using the connect function. First, I’ll write a function called MapStateToProps that takes the state of the redux chore and returns the props for the presentational component calculated from it.

These props will be updated anytime the state changes. Next, I write a function that I call MapDispatchTheProps. It takes these chores dispatch method as its first argument. It returns the props that used the dispatch method to dispatch options, so it returns the callback props needed for the presentational component.

To create the container component from them, I import connect from the react redux library and I call it parsing MapsStateToProps as the first argument and will dispatch the props as a second argument.

Finally, I close the function called Param and I open another param, because this is a parent function and it needs to be called twice. The last argument is the presentational component that I want to connect to the redux chore.

The result of the connect call is the container component that is going to render my presentational component. It will calculate the props to pass through the presentational component by merging the objects returned from MapStateToProps, map dispatched to props, and its own props.

React 公式よりももっと低レベルなところから始める、React チュートリアル

React が必要になる状況

いつ React が必要になるのでしょうか?

例えば次のサンプルのように、DOMを増減するアプリケーションがあるとして、設計について特に考慮せずにjQueryで単純にDOMを増減させると、目的は達成できるのですが、現在のアプリケーションの「状態」を確認することが非常に難しくなります。例えば、青いブロックが今何個あるのか、といったことを確認するためにはDOM全体を捜査しなければわかりません。

See the Pen React easy tutrial1 by nakanishi (@nakanishi) on CodePen.

そして、状態の管理が難しいと、いつかアプリケーションが破綻します。

上記のアプリケーションがなぜ状態管理が難しいか

上記のアプリケーションの状態管理がなぜ難しいかというと、状態がすべて本物のDOMとして管理されているために、毎回それを捜査・取得する必要があるからです。もし最初からJSの変数に情報が入っていれば、こんなことはしなくてすみます。

ですから、状態をJSで管理して、その状態をjQueryで反映させる、というコードに書き換えてみます。

jQueryで、状態をrenderするような書き方

次のコードは、一箇所に状態を集めて、その状態を元にDOMを作成し、レンダリングするような方式をとっています。

See the Pen React easy tutrial2 by nakanishi (@nakanishi) on CodePen.

ただしこれでもマイナス点はあって、一旦DOMをすべて削除してから、再度すべてを再レンダリングしているので、無駄が非常に多いという問題があります。できれば変更されたところだけをレンダリングし直してほしいわけです。そのほうが負荷を小さくできるわけですから。

それを実現してくれるのがReactやVueといった、仮想DOMというシステムもとにしたライブラリやフレームワークです。

Reactを始める

次のコードはReactを使ったコードです。ボタンをクリックすると、Hello,の後ろの名前が変更されます。しかしこの変更は先ほどまでのコードのようにjQueryでDOMを直接変更してはいません。あくまで、「状態管理をしている変数の値だけを変更」しています。そして、状態が変更された結果、Reactがそれを察知して、View=実際に目に見えるDOMを変更します。

See the Pen React myTutrial1 by nakanishi (@nakanishi) on CodePen.

//このソースではヘッダーでreactとreact-domライブラリを読み込んだのと同じ状態になっている
//npmをES6シンタックスでインポートする場合には、以下のコードを冒頭に書く
//import React from 'react'
//import ReactDOM from 'react-dom'

//Helloコンポーネントをつくる
class Hello extends React.Component {
  constructor() {
    super();
	//状態をもつ。状態は単なるJSオブジェクトで管理する。
	this.state = {
		name: "name"
  	};
}
	
	textChange(text) {
		//setStateメソッドはリアクトコンポーネントが最初から持つメソッドで、
		//this.stateを変更するもの。
		this.setState({name:text});
	}
	
	//renderでreturnしたものが、コンポーネントを呼び出したときに、レンダリングされる内容
	//returnの内容が複数行にわたる場合は、()でくくると良い。
  render() {
    return (
			//{}の中はJSとして解釈される
			//this.state.nameはこのコンポーネントの状態のうち、
			//nameというプロパティを持つもの。これを参照して、表示させている。
      <div>
        <h1>Hello, <span className="name">{this.state.name}!</span></h1>
				<button onClick={()=>{this.textChange("Mark")}}>Mark</button>
				<button onClick={()=>{this.textChange("Evan")}}>Evan</button>
      </div>
			//onClick={}の中身が、クリック時に実行される。
			//ここではES6のアロー関数を用いて、自身のメソッドであるthis.testChangeを呼び出している。
    );
  }
}

//argument1が、どのコンポーネントを描画するか。
//argument2がどの対象にReactを紐付けるか。
ReactDOM.render(
  <Hello />,
  document.getElementById('root')
);

一番シンプルなリアクトApp

https://codesandbox.io/s/j1wn8ko1y9

Freezeとexpectで、mutateのチェックと、テスト

//reducer
const todos = (state = [], action) => {
	//受け取ったアクションのtypeによって切り替わる
	switch (action.type){
		case 'ADD_TODO':
			//stateは配列なので、その中に追加で新しいオブジェクトを与える。
			//与える新しいオブジェクトは、渡されたactionの中の情報を元に生成される
			return [
				...state,
				{
					id: action.id,
					text: action.text,
					completed: false,
				}
			];
	}
};

//deepFreezeはmutateしていないかをチェックするライブラリ
//expectはテスト用のライブラリ
const testAddTodo = () => {
	const stateBefore = [];
	const action = {
		type: 'ADD_TODO',
		id: 0,
		text: 'Test Text',
	};
	
	const stateAfter = [{
		id: 0,
		text: 'Test Text',
		completed: false
	}];
	
	//stateBrforeとactionがmutateしていないかをチェック
	deepFreeze(stateBefore);
	deepFreeze(action);
	
	//todosというファンクションを実行した時に、
	//帰ってくる値が、stateAfterと同じかを.toEqualメソッドで確認
	expect(
		todos(stateBefore, action)
	).toEqual(stateAfter);
};

//テストを実行。問題あればコンソールにでる。(クロームのコンソールの方をチェック)
testAddTodo();
console.log('All tests passed');

See the Pen BdadMV by nakanishi (@nakanishi) on CodePen.

Redux チュートリアルで必要になったES6記法 immutableに配列やオブジェクトを変更する

// オブジェクトを引数として受けて、それを展開する書き方
// Propertyがvalueとnameのものを展開して、valueとnameで受ける
const testFunction = ({value,name}) => (value + name)

const testObject = {
	value: "a",
	name: "b",
}

console.log(testFunction(testObject));
console.log("tesf")

//リストに新たな項目を追加する方法
const list =[0,1,2,3];

const addList = (list) => {
	return [...list,"add"];
}

console.log(addList(list));
// slice(n)はn番目を含んでそれ以降の配列を返す
var newList = list.slice(2)
//console.log(newList);

// slice(0,n)は0から、n番目を含まない、その範囲の配列を返す
var newList = list.slice(0,2)
//console.log(newList);

// slice(m,n)はmから、n番目を含まない、その範囲の配列を返す
var newList = list.slice(1,2)
//console.log(newList);
// index 番目(0から始まるやつで) の配列だけを削除するFn
const removeCounter = (list, index) => {
  // Old way:
  //return list
  //  .slice(0, index)
  //  .concat(list.slice(index + 1));

  // ES6 way:
  return [
    ...list.slice(0, index),
    ...list.slice(index + 1)
  ];
};

console.log(removeCounter(list,1))

See the Pen arrow function object by nakanishi (@nakanishi) on CodePen.

//オブジェクトにオブジェクトをマージする場合の書き方
const addObject = (lastObject, addOne) => {
	//からのオブジェクト{}に、どんどん上書きしていく
	return Object.assign({}, lastObject, addOne)
}

const lastObject = {
	name: "name",
	value: "value"
}

const add1 = {
	name: "name2",
	value: "value2"
}

const add2 = {
	newProp: "newProp"
}

//同じプロパティがあれば、上書きされる
var show = addObject(lastObject, add1);
//console.log(show);

//同じプロパティがなければ、新たにプロパティが作られる
var show = addObject(lastObject, add2);
console.log(show);

See the Pen JyjypY by nakanishi (@nakanishi) on CodePen.

function returnInt(element) {
  return parseInt(element, 10);
}

['1', '2', '3'].map(returnInt); // [1, 2, 3]
// Actual result is an array of numbers (as expected)

// Same as above, but using the concise arrow function syntax
['1', '2', '3'].map( str => parseInt(str) );

Redux 公式ドキュメント 日本語に一部翻訳

http://redux.js.org/

Redux の概要

The whole state of your app is stored in an object tree inside a single store.
The only way to change the state tree is to emit an action, an object describing what happened.
To specify how the actions transform the state tree, you write pure reducers.

あなたが作っているアプリケーションの状態 state を全て、たったひとつのオブジェクトで管理し、そしてそれを”store” という変数に入れる。(訳注:もしくは store という概念と紐付けて運用する) 状態を変更する方法は制限されており、”action”を発行する(=emit) 方法だけしかない。action は”何を起こすか”が述べられているオブジェクトである。”action”が状態に対して、どのような変更を加えるのかは、”reducer” によって定義する。reducer は純粋関数である必要がある。

(訳注:純粋関数については例えばこの記事を参照。Redux と state の関連では、私が理解する限り、関数の引数で与えられたもの以外の変動する値を関数内部で使わない(例えば引数では与えられていないグローバル変数など)、引数で与えられたものそのものを変更しない=イミュータブル、return で新たなstateを返す、というルールを守れば良い。)

That’s it!

Redux の要旨はそれで全て!

“Redux 公式ドキュメント 日本語に一部翻訳” の続きを読む