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;

CSS Transition と Keyframe Animation 違いと優位性

いつもはVelocity.jsをつかってアニメーションを書いているのですが、マウスホバー時のアニメーションをリッチにしたり、ReactでDOMを再レンダリングした時に目を引くためのアニメーションをさせる、そんなときにはCSSベースでアニメーションを書いたほうが、メンテナンスが簡単そう等々、利点があるなと最近感じました。

そこでTransitionとKeyframeを使ったアニメーションに関して、いくつか役にたった記事を集めて、英語のものは勝手に翻訳します。

ざっくりデモ https://codepen.io/nakanishi/pen/gxQzoZ

CSS Transitions VS Keyframe Animations

There are currently two ways to animate things with CSS:

現在、アニメーションをCSSで実装する方法は2つあります。TransitionとKeyframe Animationです。
  • Transitions
  • Keyframe Animations

Each technique has similarities and differences. Here’s how they work.

それぞれの技術は同じ点もありますし、異なる点もあります。これらの技術がどのように機能しているのか、みていきましょう。

Transitions

Transitions work by morphing a property from one value to another when the transition is triggered.

Transitionは、Propertyをある値から別の値へと変化させることで、動作します。これはトランジションがトリガーされた際におきます。

Here is a simple example (hover your mouse over the box to trigger the transition):

次の簡単な例をごらんください。

JS Bin

There are several ways to trigger a transition. The most common way is with the :hover pseudo-class (which you saw in the example above), but others include:

トランジションをトリガーする方法はいくつかあります。一番一般的な方法は、:hover疑似クラスを用いる方法ですが、他にも方法があります。

  • :active
  • :focus
  • :checked
  • :disabled
  • page load
  • media queries
  • device orientation
  • class changes (Triggered via javascript)

(By the way, there’s a great article by Louis Lazaris demonstrating some examples of these techniques) これらのテクニックを使ったサンプルが上記の記事で紹介されています。

In all cases, a user performs some action, which sets our transition in motion. You can adjust many properties of the transition, like the delay or timing, but all transitions must have a beginning and an end.

どのケースにおいても、ユーザーがなんらかのアクションを起こし、それがトランジションにモーションを与えます。トランジションの多くのpropertyを調整することが出来ます。例えば、delayやタイミングを調整することができます。しかし、Transitonの場合には、必ず開始と終了が存在します。

Keyframe Animations

Keyframe animations are similar to transitions, in that they can be used to morph properties from one value to another, but they differ in how they are defined. You define them by identifying the keyframes that make up your animation and giving that set of keyframes a name. Then, you can invoke those keyframes anywhere you want, using CSS selectors. Let’s look at an example:

Keyframe animation は次の点ではTransitionと同じです。つまり、propertyをある値から別の値へと変化させるという点においては同じです。しかし、定義の仕方が異なります。Animationを構成するKeyframeを定義し、そのKeyframe全体に名前を与えます。その後、そのkeyframeを必要な箇所で呼び出します。その際にはCSSセレクタを用います。例を見てみましょう。

JS Bin

As you can see, we’ve defined our “pulse” keyframes, and applied it to several elements.

上記の例では、pulseという名前のkeyframeを定義し、それをいくつかの要素に対して適応しています。

Which is Better?

Both have their strengths and weaknesses. Here are a few of the main benefits I’ve found for each option:

どちらの機能にも強みと弱点があります。それぞれの選択に対する主要な利点を紹介します。

Benefits of Transition:

  • Slightly better browser support (compare transitions to animations)
  • 多少ブラウザーサポートの点で優れている(訳注:ただし2017年現在ではどちらもほとんどサポートされているので、この点はあまり考慮する必要がないかも。)
  • Familiar syntax
  • 親しみやすいシンタックス
  • Simplicity
  • 明快さ
  • Easy to manipulate in Firebug/Devtools
  • FirebugやDevtoolで扱いやすい

Benefits of Keyframes:

  • More granular timing control
  • タイミングをより詳細にコントロールすることができる
  • Easy to mix and match properties (one keyframe definition can animate color and opacity, and size, etc.)
  • 複数のプロパティを組み合わせたり、そのタイミングを合わせるのが簡単。(一つのキーフレームに、色の変更や、透明度の変更や、サイズの変更、というように複数のアニメーションを指定できる。)
  • More animation options (infinite, alternate, etc.)
  • infiniteやalternateなど、より多くのアニメーションに関するオプションがある
  • Keeps code DRY
  • コードをDRYにすることができる。

Personally, I feel like animations with keyframes are more powerful, but it really comes down to your specific application (for example, I chose to use transitions in AnchorJS and keyframe animations for my Flying Toasters).

個人的にはkeyframeを使ったアニメーションのほうが強力かなと思いますが、しかし、それぞれの状況にあわせて選択することになるでしょう。例えばAnchorJSにおいてはtranstionを使いますし、私のフライングトースターのアニメーションにはkeyframeを選択しました。

Finally, one property that is often confused with these animation techniques is transform. While transform is new and can do some neat things (like rotate, scale, translate, etc), it doesn’t animate anything. It’s a typical css property like font color or opacity.

最後に、これらのアニメーションに関する技術と、混同されているpropertyがあります。それはtransformです。transformは、新しく素晴らしい効果をもたらしてくれるものですが(rotateやscaleやtranslateなど)、アニメーションをさせるものではありません。これはCSSのプロパティであって、font-colorやopacityといったものと同じです。

CSS3 Transitions Without Using :hover

Up to this point, the most common use for CSS3 Transitions has been in conjunction with the well-known CSS :hover pseudo-class.

今までのところ、CSS3 Transitionの一番よくある使い方は、これまたよく知られた :hover 擬似クラスと組み合わせて用いる方法でした。

Here’s a typical transition that changes link color on mouseover using pure CSS:

次の例は、transitionを使った典型的なもので、リンクカラーを、マウスホバー時に変更するものです。これは全て純粋なCSSによっておこなわれています。

a, a:link, a:visited {
  color: lightblue;
  -webkit-transition: color .4s linear;
  -moz-transition: color .4s linear;
  -o-transition: color .4s linear;
  -ms-transition: color .4s linear;
  transition: color .4s linear;
}

a:hover {
  color: white;
}

This will animate the color property when you hover over a link on the page. Pretty simple, and you’ve probably seen or used something similar. But transitions are not just limited to use with :hover.

このコードはcolorプロパティを、aリンクがホバーされた際に変化させます。とてもシンプルなものであり、また多分過去にあなたも見たことがあるか、実際に書いたことがあるのではないかと思います。しかし、トランジションを使えるのは:hoverだけではないのです。

You can animate CSS properties via transitions using some other CSS techniques, a number of which I’ve outlined below. I’ve also included a demo for each example.

CSSプロパティをtransitionを用いてアニメーションさせるテクニックは色々あり、その概要を書き出しました。それぞれの項目には、デモも付けました。

Transitions Using :active

The :active pseudo-class matches any element that’s in the process of being activated. The primary way that an element is “activated” is by means of a mouse click, or mouse down.

:active擬似クラスは、全てのactiveな状態にある要素とマッチします。主な、要素をactiveにする方法は、クリックする、もしくはマウスを押し込んだ状態にすることです。

Here’s some CSS and an accompanying demo that demonstrates using :active along with CSS3 transitions to mimic a mousedown event:

次のCSSは、:activeを使ったデモです。CSS3 Transitionを使って、mousedownイベントを検知した時に発動するようになっています。

.box {
  width: 300px;
  height: 300px;
  background: #222;
  -webkit-transition: width 2s ease, height 2s ease;
  -moz-transition: width 2s ease, height 2s ease;
  -o-transition: width 2s ease, height 2s ease;
  -ms-transition: width 2s ease, height 2s ease;
  transition: width 2s ease, height 2s ease;
}

.box:active {
  width: 500px;
  height: 500px;
}

With this code, the box’s width and height properties are animated to become larger as you hold the mouse down on the element. Once you release, the box animates back to its original dimensions.

このコードは、四角の横幅と高さのpropertyがアニメーションされており、要素の上でマウスダウンしている間、それが大きくなります。マウスを離すと、元のサイズに戻ります。

Here’s a demo:

Transitions Using :focus

You can use the :focus pseudo-class to do something similar. This time we’ll use a form, and we’ll animate the width of any form element that receives focus:

:focus 擬似クラスを使って、同様のことができます。今回はform要素を使いましよう。form要素にフォーカスが当たった場合に、幅をアニメーションさせてみました。

input, textarea {
  width: 280px;
  -webkit-transition: width 1s ease;
  -moz-transition: width 1s ease;
  -o-transition: width 1s ease;
  -ms-transition: width 1s ease;
  transition: width 1s ease;
}

input:focus, textarea:focus {
  width: 340px;
}

And here’s a live demo:

Transitions Using :checked

You can animate checkboxes and radio buttons when they become “checked” — although you’re limited with what you can do with those, since you can’t really change their native styling.

checkboxとradio buttonを”check”されたときに、アニメーションさせることもできます。ただしボタンに対してできることは限られています。何故ならnativeのスタイリングを変更することはできないからです。

We’ll just do a simple width change, which will appear to indent any selected checkbox:

シンプルな変更を加えてみることにしました。これによって選択されたチェックボックスは、インデントされたようになります。

input[type="checkbox"]:checked {
  height: 20px;
  -webkit-transition: width 1s ease;
  -moz-transition: width 1s ease;
  -o-transition: width 1s ease;
  -ms-transition: width 1s ease;
  transition: width 1s ease;
}

input[type="checkbox"]:checked {
  width: 30px;
}

And here’s a simple demo:

Transitions Using :disabled

Keeping with the theme of web forms, this time we’ll combine CSS3 transitions with some jQuery to animate the background color of form elements when they become disabled via the disabled attribute:

引き続きformを扱っていきます。今回は、CSS3 TransitionとjQueryを組み合わせて、formの背景色をアニメーションさせます。disabledアトリビュートによってdisableになった際にこれが発動するようにしました。

input[type="text"], textarea {
  background: #e2e2e2;
  -webkit-transition: background 1s ease;
  -moz-transition: background 1s ease;
  -o-transition: background 1s ease;
  -ms-transition: background 1s ease;
  transition: background 1s ease;
}

input:disabled, textarea:disabled {
  background: #666666;
}

And the quick-and-dirty jQuery that adds/removes the disabledattribute is:

そして非常に雑ではありますが、disabledアトリビュートをつけたり外したりするjQueryのコードは以下のようになります。

$(function() {
  $('input[type="radio"]').click(function() {
    if ($(':checked').val() === "other") {
      $('input[type="text"]').removeAttr("disabled");
    } else {
      $('input[type="text"]').attr("disabled", "disabled");
    }
  });
});

So when the last radio button is selected (the one with a value of “other”), the text box has its disabled attribute removed. If another option is selected, the disabled attribute is re-applied.

つまり、ラジオボタンの最後のものを選択すると(このボタンはotherというvalueを持っています)、テキストボックスはdisableといいうアトリビュートが鳥のどかれます。それ以外のラジオボタンが選択されると、disabledアトリビュートが再度適用されます。

The :disabled pseudo-class is dependent on that attribute being present, so the animation will occur whenever that attribute is added or removed.

:disabled 疑似要素は、現在のその属性がどのような状態であるかということに依存しますので、そのためアニメーションはそのアトリビュートが追加されたり削除されるときに、発動します。

Here’s the demo:

Transitions Using Media Queries

This last one may be the least practical, because let’s face it, the only people that ever resize their window to see what happens are web developers.

最後にとりあげるこのテーマはあまり実践的ではないかもしれません。というのも、ウィンドウサイズを変更して、何が起きるかをまじまじと観察するような人間は、ウェブディベロッパーくらいだからです。

Nonetheless, this is just another way to use CSS3 transitions. The new Modernizr design does this.

とにかく、このサンプルでは先程とは違った方法のCSS3 Transitonが使われています。新しいModernizrのデザインでもこれが使われています。

Here’s the code:

.box {
  width: 440px;
  height: 440px;
  background: #222;
  margin: 0 auto;
  -webkit-transition: width 2s ease, height 2s ease;
  -moz-transition: width 2s ease, height 2s ease;
  -o-transition: width 2s ease, height 2s ease;
  -ms-transition: width 2s ease, height 2s ease;
  transition: width 2s ease, height 2s ease;
}

@media only screen and (max-width : 960px) {
  .box {
    width: 300px;
    height: 300px;
  }
}

This example animates two different properties simultaneously, separating the two by a comma. The media query tells the box to shrink if the screen size goes below 961px.

上記の例では2つの異なるプロパティを同時にアニメーションさせています。それぞれの値はコンマで仕切られていますね。メディアクエリーはboxに、スクリーンサイズが961以下になった場合に、縮まるように定義されています。

Resize your window in the demo page to see it work:

Some Notes About the Code

If you’re wondering about the code, I’ve included the standard property last, even though it’s not supported by any browser that I know of.

どんなブラウザでも対応できるように、prefixとそれから標準的なプロパティを最後に追加しています。

Also, I’ve included the -ms- prefix, even though IE9 and IE10 do not yet support transitions. But evidently they are coming in IE10, so it’s worth including an extra line.

同じくprefixに関して。今はIE11が標準的に対応しなくてはいけないブラウザなので、ここは関係ない。

And the code examples that you can see in this post aren’t exactly the same as those used in the demo pages. I’ve made the code as brief as possible for the purpose of focusing only on the parts being discussed in this article.

デモコードは少し変えている。

Are There Other Ways?

This is pretty much all I could come up with for alternate ways to use CSS3 transitions. If you can think of another, let me know.

CSS3: Animations vs. Transitions

In CSS, you have two techniques for visualizing change that are competing for your attention: Animations & Transitions. In this article, let’s examine the similarities and differences between them so that you can know when to use which.

CSSにおいて、ユーザーの注意を引くための、視覚的な変化をもたらすための技術には、大きく分けて2つあります。一つはAnimationで、もう一つはTransitonです。この記事では、その2つの技術の同じ部分と異なる部分を精査していき、どちらを選択するばよいのか、その指針を示すことにします。

To make the most of this article, it would be helpful for you to be familiar with using both animations and transitions. If you haven’t had a chance to get your hands dirty with them, the Creating a Simple CSS Animation and Looking at CSS3 Transitions tutorials will help you get started.

この記事を最大限活用するためには、あなたが既にある程度AnimationとTransitionの技術に馴染みがあるほうがいいでしょう。実際に手を動かしてこれらの技術を使ったコードを書いたことがないのであれば、まずは上記2つのチュートリアルから始めるといいかもしれません。

Similarities

From a distance, both animations and transitions are very similar. They both allow you to:

大枠でいえば、animationとtransitionはどちらも非常に似ています。どちらも次のことができます。

  • Specify which CSS properties to listen for changes on
  • Set timing (easing) functions to alter the rate of going from a one property value to another
  • timing(イース)ファンクションを設定することで、プロパティの値の変化の進み具合を定義することが出来る。
  • Specify a duration to control how long the animation or transition will take
  • durationを設定することで、animatioやtransitionがどれくらいの時間をかけて変化するかを指定できる。
  • Programmatically listen to animation and transition-specific events that you can then do with as you wish
  • Visualize CSS property changes.

Beyond this point, though, you will see that animations and transitions diverge a bit and let their uniqueness shine through. Let’s look at those unique qualities in greater detail.

上記以外のことがらに関しては、animationとtransitionには少し違いがあり、その違いがお互いの良さを生じさせています。ではそれぞれの特質をより詳細にみていきましょう。

Differences

Animations and transitions show their differences when it comes to how you trigger them to play, whether they loop easily, how complicated of a transition you can define, how formal you must be in being able to use them, and how well they play with JavaScript. Let’s explore those topics in greater detail.

AnimationとTransitionの違いがはっきりと現れるのは、次のような点です。どのように開始のためのトリガーをするか。どれくらいループをさせることが簡単か。どれくらい複雑に変化を指定できるか。使用するためにどれくらい形式的な理解が必要か。そしてJavaScriptと組み合わせた時にどれくらい上手く動くか。ではこれらのトピックについて考えてみましょう。

Triggering

One of the major differences between animations and transitions can be seen in how you trigger them to start playing.

大きな違いの一つは、トリガーの方法です。どのように再生をスタートさせるか、という部分が異なります。

A transition only plays as a reaction to a CSS property that has changed. A common scenario is one where you use the :hover pseudo class to change the value of a CSS property:

Transitionは、CSSプロパティの変更に対してのみ反応し、再生をおこないます。よくあるのは、:hover擬似クラスを用いてCSSプロパティの値を変更する方法です。

To use the example visualized here, if a transition is defined, you would be able to see the circle growing from its normal size to its hover size. Another way of triggering a transition is to use JavaScript to programmatically add or remove CSS classes to simulate a CSS property change. Rounding out our ways of making a property change, you can use JavaScript to set an inline style that changes a property your transition is listening for.

上記の例を使って説明をします。transitionを定義しているので、通常のサイズからホバーしたサイズへと、円が大きくなっていくことが確認できます。ホバー以外の方法としては、JSを使ったプログラミングによってCSSクラスを追加したりすることでCSSプロパティを変更する方法もあります。つまりJSを使ってインラインスタイルに、プロパティを変更するような変更を加えます。しかもtransitionが待ち構えているプロパティを変更します。(訳注:「transiton: width 2s」となっている要素に対して、widthを例えばjQueryを使って$(‘.target’).width(400)と指定すればアニメーションする。)

Animations, on the other hand, don’t require any explicit triggering. Once you define the animation, it will start playing automatically. Yep, that’s how animations roll!

Transitionに対して、Animationの場合は、トリガーを明示的に宣言する必要はありません。一度アニメーションを定義してしまえば、自動的に再生されます。

Looping

This is pretty simple. Animations can be easily made to loop by setting the animation-iteration-count property. You can specify a fixed number of times you want your animation to repeat:

この話題に関して結論は非常にシンプルです。Animationはanimation-iteration-countプロパティを使うことで、簡単にループを設定することができます。アニメーションを繰り返す回数を具体的な数字で指定することができます。

animation-iteration-count: 5;

If you just want your animation to loop forever, you can do that as well:

無限にループさせた場合は、次のようにすることで実現できます。

animation-iteration-count: infinite;

Transitions, on the other hand, don’t have a property that specifies how many times they can run. When triggered, a transition runs only once. You can make a transition loop by fiddling with the transitionEnd event, but that isn’t particularly straightforward – especially when compared with animations.

それに対してTransitionの場合には、繰り返し何回も再生するように指定するpropertyはありません。トリガーされると、トランジションは一度だけ実行されます。transitionをループさせることは、transitonEndイベントを扱うことで実現できますが、しかしそれはあまり正攻法ではありません。とくにAnimationと比べた場合にはかなり複雑な方法です。

Defining Intermediate Points / Keyframes

中間点の定義 / Keyframeの場合

With an animation, you have the ability to define keyframes which give you more control over your CSS property values beyond just the start and the end:

Animationの場合、keyframeの定義によって、CSSプロパティの値をよりコントロールすることができ、開始と終了以上の定義ができます。

You can set as many keyframes as you want, and when your animation plays, each keyframe will be hit with the specified property changes reflected. This allows you to create the kinds of involved animations that help HTML5 compete with more established animation technologies like Flash more effectively.

keyframeは望む数だけ、何個も設定できます。アニメーションがスタートすると、それぞれのkeyframeの位置で指定されたpropertyの変更が反映されます。これによってHTML5で、他の洗練されたFLashのようなアニメーション用のテクノロジーに、匹敵する効果を作り出すことができます。

With a transition, you don’t have much control over anything beyond the end result:

Transitionでは、最初と最後の指定以上の、複雑なコントロールはできません。

A transition simply goes from an initial state to the final state. You cannot specify any points in-between like you can with an animation, so a transition might not be a good choice if you are trying to create the next Teen Girl Squad sensation or a complex animation.

Transitionは単純に、初期状態から、最終的な状態へと、推移させることしかできません。keyframe animationのように、中間点を指定することはできないのです。なのでtransitonでは、Teen Girl Squadのような刺激的で複雑なアニメーションを作るのには向いていません。

Specifying Properties Up-Front

The next thing I will describe is how formal animations and transitions are when it comes to defining a transition between CSS property values.

次の話題は、どれくらい規則だった定義が、アニメーションにおいて必要か、という観点です。

On the formal side, you have transitions. Every CSS property you want recognized by your transition must be explicitly represented.

もし規則だった書き方をしたいのであれば、Transitionに軍配が上がるでしょう。Transitionに反応して欲しい全てのCSSプロパティを、明示的に書く必要があります。

For example, let’s say you have something like the following:

例えば、以下のようなコードを書いたとしましょう。

#mainContent { 
        background-color: #CC0000; 
        transition:background-color .5s ease-in; 
} 
#mainContent:hover { 
        cursor: pointer; 
        background-color: #000000; 
        width:500px;
}

Upon hover, I specify a different value for both background-color as well as width. My transition specifies only background-color though. This means your browser is only listening for changes on the background-color property.

hoverした場合には、通常時とは異なる2つのプロパティの値を指定しています。バックグランドカラーと幅です。ただし、Transitionではバックグランドカラーだけを指定しています。つまり、バックグラウンドカラーの変更だけを、監視することになります。

If I wanted my transition to affect both the background-color and width properties, I will need to explicitly add another transition entry for width:

もしバックグラウンドカラーとwidthの2つのプロパティをトランジションしたい場合には、明示的にwidthもtransitionに加える必要があります。

#mainContent { 
        background-color: #CC0000;
        transition:background-color .5s ease-in, width .5s ease-in 
} 
#mainContent:hover { 
        cursor: pointer; 
        background-color: #000000; 
        width: 500px;
}

What About transition: all?

全てのプロパティをトランジションする場合にはどうすればよいか

You do not have to specify every property that you care about when using a transition. You could simplify your life by using the all value instead: transition: all .5s ease-in. I do not recommend this because you will take a performance hit. Your browser is now listening for a whole lotta properties as opposed to just a few that you know you will be modifiying. Unless you have a strong need to do this, I would recommend specifying each CSS property you wish to transition individually.

Transitionを使う際に、全てのプロパティを明示的に指定する必要はありません。allという値を代わりに使えば、シンプルに全てのプロパティををトランジションさせることができます。「transition: all easein」といった具合です。とはいえ、これはあまりおすすめしません。何故ならパフォーマンスが下がるからです。こうした場合、ブラウザは沢山存在する全てのプロパティを監視するからです。それなのにあなたが変更するプロパティは少ししかありません。こうすべき強い必要性がない限りは、transitionさせたいプロパティをそれぞれ指定することをおすすめします。

With animations, you have the ability to specify properties at a whim in each keyframe without having to do anything that resembles declaring them:

Animationにおいては、以下のようにすればいいです。

keyframes imageSlide { 
        0% { 
                left: -150px;
        } 

        20% { 
                left: 50px; 
                height: 200px;
        } 

        80% { 
                left: 200px; 
                height:300px;
        } 

        100% { 
                left: 600px; 
                background-color:#FFFFFF;
        } 
}

In this example, the height and background-color of whatever element I am animating will smoothly transition when the appropriate keyframe is reached – even if the property was never listed before!

このように、適切なアニメーションが各keyframeで発動します。そために、前もって変更するプロパティのリストを作っておく必要はありません!

Interaction with JavaScript

In many cases, a transition or animation you declare in CSS will be good enough. You specify in CSS your starting value, the ending value, and any intermediate values that you want your properties to take. Your animation or transition will read these values and take care of business from there. This scenario works best when what you are wanting to do is predefined. There will be times when you want to alter the value of a property that you are animating based on some external input – a mouse click, the result of some calculation, etc.

多くの場合において、CSSで実装するtransitionやanimationといった機能は、それだけで十分な役割を果たしてくれます。CSSで開始時の値を定義して、終わりの値も定義して、そして中間点を定義して、といった具合に。AnimationやTransitionはそれらの値をしっかり読み取って、それぞれの地点で自分の仕事を遂行します。どうしたいかが事前に決まっている場合には、これで役割をしっかりとこなすことができます。しかし、値を、外部の入力値に基づいて、アニメーションを変更したい場合もあるでしょう。例えばマウスクリックや、ある種の計算の結果を使用する場合です。

For such interactions, property values entirely predefined in CSS is a bit limiting. You can decide in such cases to rely on JavaScript, but going all-in on JavaScript alone may be too extreme as well. What you want is a hybrid approach where your animation or transition is declared primarily in CSS but certain aspects of which are manipulated using JavaScript.

このようにインタラクションが必要な場合には、CSSに予め記述された値だけでは、できることが限定されてしまいます。そういった場合には、JSを使用することを検討すると思いますが、かといって全てJSだけで実装するのはやりすぎだというようなケースがあります。そういう場合には、CSSアニメーションとJSのハイブリッドというアプローチも選択肢に入るはずです。animationやtransitionで予め大部分をCSSにかいておいて、しかしある部分はJSで操作する、といった方法です。

When it comes to combining JavaScript with either an animation or transition, there is no contest – you almost always want to use a transition. Using an animation with JavaScript is possible…in much the same way it is possible to win at the cinnamon challenge. It isn’t impossible to make it work, but chances are, you don’t want to do it. The reason for this difference has to do with how transitions and animations work.

JSと組み合わせるという観点から言うと、はっきりいって勝負は見えています。ほとんどのケースでは、transitionを使うことになるでしょう。Animationを使う方法も無理ではないのですが、そうしようと思う機会はかなり少ないはずです。その理由は、transitionとanimationの挙動に違いがあるからなのです。

Animations are very specific in what they do. The @keyframes rule clearly lays out the path your animation will take as it is running. Attempting to change your animation in JavaScript requires a very complicated series of steps that involves actually modifying the @keyframes style rule itself. If you’ve ever had to manipulate CSS that lives inside a style rule, you know that it is pretty unintuitive.

Animationの場合は、何をするのかということをかなり具体的に定義します。@keyframeによってアニメーションがどのような状態を変遷していくのかを、明確に定義します。JSによってアニメーションを変更しようとすると、かなり複雑な作業が必要になります。@keyframesを書き換えないといけないからです。インラインで記述されたCSSをマニュピレイトしたことがある人ならわかると思いますが、これはかなり直感的ではありません。

Contrasting the predefined path of an animation is the transition. Transitions are not as well defined as they may seem. Your transition will kick in when a property it is listening for changes. This property change can be set entirely via only CSS:

Transitionの場合は、そこまで定義をしていません。トランジションは、待ち受けていたプロパティの変更があった場合に、開始されます。下記のコードではプロパティの変更はCSSの中でなされていますね。

#myElement {
        background-color: #FFF;
        transition: background-color .2s ease-in;
}
#myElement:hover {
        background-color: #000;
}

This change can also be accomplished via JavaScript where you modify a CSS property the transition is listening for by setting an inline style:

CSSプロパティの変更はJSからも可能です。インラインに書かれたトランジションが待ち受けるプロパティを、JSから変更しましょう。

var myElement = document.querySelector("#myElement");
myElement.style.backgroundColor = "333";

The transition doesn’t care how the properties it is listening for changes. As long as the property changes somehow, the transition will get to work. This means, for interactive scenarios that don’t involve a predefined starting and ending point, you can do a lot of interesting things by deferring all transition-related heavy lifting by using the transition declaration. The actual values of the properties you are wanting to transition can be specified using JavaScript.

transitionは、変更を監視しているプロパティがどんな方法で変更されるかは、まったく気にしていません。とにかくプロパティが変更されれば、Transitionが発動します。つまり、予め始まりと終わりが決まっていないインタラクティブなアニメーションを実装する場合に、transtionの対象になっているプロパティを変更することで、様々な面白い効果を得られる、ということです。望むプロパティの値をJSを使って指定することができます。

To help visualize what I just wrote, let’s look at a simple example:

Click anywhere in the gray box to have the circle move to the point of the click. Keep clicking around to see the circle keep moving.

灰色のboxの中でクリックすると、円がその場所に移動します。クリックして、円が移動するのを確認してください。

How this works is pretty simple. The actual movement is handled by the transition. Knowing where to transition to is handled by the JavaScript which sets the top and left property values on the element. Because the transition is listening for changes to the top and left properties, any change results in your transition kicking in. The end result is exactly what you wanted. Best of all, you didn’t have to write any JavaScript for handling the actual movement itself. As a bonus, because the transition is declared in CSS, your browser optimizes it heavily so that it runs really smoothly.

仕組みは非常に簡単です。実際の動きは、transitionによって実装されています。どこへ移動すべきなのか、ということはJSを使って制御されています。JSによってtranstionが監視している、leftプロパティとtopプロパティを変更しています。変更が発生すると、transitionが起動します。その結果希望する結果を実現しています。一番いいのはJSを全く書かないで実装する方法ではありますが。副次的な利点としてtranstionはCSSで宣言されているので、ブラウザーはパフォーマンスを最大化してくれ、結果として非常にスムーズに動きます。

This friendship between transitions and JavaScript is so full of win, it hurts just writing about.

transitionとjsの組み合わせは、非常に有効です。

Conclusion

There you have it – a candid look at what makes transitions and animations similar yet so very different. My general approach for determining when to use which goes like this:

TransitionとAnimationが基本的には似ていて、それでいて異なる部分もかなりある、ということをみてきました。どちらを使うべきなのか、ということに関しての私の選択基準は、以下の様なものです。

  • If what I want requires the flexibility provided by having multiple keyframes and easy looping, then I go with an animation.
  • keyframeと簡単に実装できるループによる柔軟性が欲しいときは、animationを選択します。
  • If I am looking for a simple from/to animation, I go with a transition.
  • シンプルに、開始と終了を設定するアニメーションを実装した場合にはtransitionを選択します。
  • If I want to manipulate the property values that I wish to animate using JavaScript, I go with a transition.
  • JSでプロパティの値を操作したい場合には、Transitionを選択します。

Now, with enough effort and JavaScript tomfoolery, you can neutralize any deficiences I list in deciding whether to use a transition or an animation. My recommendations are based on the common cases where you take a transition or animation mostly at face value. Herculean efforts to change their default behavior is admirable but often unnecessary.

もちろんJSで色々とがんばれば、どちらの機能を選択するか、を検討する際にあげたそれぞれの欠点を埋め合わせることはできます。しかし、一般的なケースにおいては上記のような選択をするのが普通でしょう。必死の努力によってこれら二つの機能の基本的な振る舞いを変更することはできますし、それは賞賛に値するのかもしれませんが、意味はありません。

日本語訳: 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.

イラストレーターでクリッピングマスクをしたときに、書き出し画像が希望のサイズにならない場合の対処

長方形ツールレイヤーと、画像の二つを選んで、クリッピングマスクをすると、レイヤーによって画像が切り抜かれる。ただしこれは見た目の上で切り抜かれているだけで、これ全体を画像として書きだそうとすると、画像のサイズがクリッピングマスクよりも大きい場合、書き出される画像のサイズは、元の画像サイズと同じになってしまう。

自分の望んだ四角のサイズに画像を書き出したい場合には以下のようにする。

クリッピングマスクは一旦解除する。グループを選んで、alt + cmd + 7

目的のサイズのレイヤーを選択して、オブジェクト⇨アートボード⇨アートボードに変換。このアートボードを書き出せばいい。

アートボード名に書き出したいファイル名の拡張子を除いたものをつける。

ファイル⇨書き出し⇨スクリーンように書き出し⇨あとはいつも通りに書き出せばいい。

この際に、ウェブデザイナーが印刷用に配置した白背景等があると、pngにしても透過しないので、これをmuteする。

下線を擬似要素で追加

img で文字やロゴを作成し、

.image {
  display: block;
  margin: 10px auto; //これは縦に並んだ要素の間隔調整用
  padding: 0 3px 5px; //ここで文字と線の間隔を調整
  border-bottom: solid 1px transparent; 線が出た時に高さが変わらないように

  &:hover {
    border-bottom: solid 1px $colorBlack; 
  }

かつ、リンクエリアが適切で、センターに来るようにする。

imageをinline-blockにして、そのうえのaはそのまま、そのさらに上のlist要素にtext alighn centerを実施

あるブロックの終わりに、任意の長さの線を引く

.target {
  &::after {
    content: "";
    display: block;
    margin: 25px auto 0;
    border-bottom: 1px solid $colorBlack;
    width: 140px;
  }
}