<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Origami</title>
    <description>The latest articles on DEV Community by Origami (@origamium).</description>
    <link>https://dev.to/origamium</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F43026%2Fe5a8044c-791d-4425-a0c5-469c0f3977d2.png</url>
      <title>DEV Community: Origami</title>
      <link>https://dev.to/origamium</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/origamium"/>
    <language>en</language>
    <item>
      <title>Promise/async関数でthrowとtry~catchはやめておこう</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Tue, 11 Feb 2020 06:32:16 +0000</pubDate>
      <link>https://dev.to/origamium/promise-async-throw-5g5l</link>
      <guid>https://dev.to/origamium/promise-async-throw-5g5l</guid>
      <description>&lt;p&gt;こんにちは。Twitterで&lt;a href="https://twitter.com/mandel59/status/1227121199810957312?s=20" rel="noopener noreferrer"&gt;完全に俺の意見ということが判明しました&lt;/a&gt;が、残しておきます&lt;/p&gt;

&lt;h2&gt;
  
  
  async関数の場合
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;


&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;f2&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;さて、間違っている箇所がわかるでしょうか？&lt;/p&gt;

&lt;p&gt;実行すればすぐにわかることですが、&lt;code&gt;async funciton&lt;/code&gt;の中で投げられた例外は&lt;code&gt;Promise.prototype.catch()&lt;/code&gt;でないと受け取ることができません。そもそもこのような間違いを犯さないためにも、&lt;code&gt;Promise&lt;/code&gt;の中のエラー送出は&lt;code&gt;Promise.reject()&lt;/code&gt;を利用すべきです。&lt;/p&gt;

&lt;h2&gt;
  
  
  Promiseの場合
&lt;/h2&gt;

&lt;p&gt;前を踏まえれば当然次のようなコードになります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nf"&gt;f2&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;終わり。asyncの中で&lt;code&gt;throw new Error()&lt;/code&gt;、asyncの利用側で&lt;code&gt;try~catch&lt;/code&gt;はやめておきましょう。&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>PWAで動いてる？isPWA();</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Tue, 28 Jan 2020 16:41:25 +0000</pubDate>
      <link>https://dev.to/origamium/pwa-55j2</link>
      <guid>https://dev.to/origamium/pwa-55j2</guid>
      <description>&lt;h1&gt;
  
  
  JavaScript
&lt;/h1&gt;

&lt;p&gt;ChromeとFirefox、iOS Safari 13以降であれば次の方法が可能です。詳しい利用可能状況はcaniuseで。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://caniuse.com/#search=display-mode" rel="noopener noreferrer"&gt;https://caniuse.com/#search=display-mode&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;(display-mode: standalone)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;matches&lt;/span&gt;
&lt;span class="c1"&gt;// true: working on PWA&lt;/span&gt;
&lt;span class="c1"&gt;// false: not working on PWA&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;iOS Safari 12以前ではdisplay-modeを利用できないので、次の方法を利用します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;standalone&lt;/span&gt;
&lt;span class="c1"&gt;// true: working on PWA&lt;/span&gt;
&lt;span class="c1"&gt;// undefined: not working on PWA&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  CSS
&lt;/h1&gt;

&lt;p&gt;CSSではdisplay-mode media queryを利用すればPWAで動いているかどうかでスタイルを変更できます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display-mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;styles&lt;/span&gt; &lt;span class="nt"&gt;for&lt;/span&gt; &lt;span class="nt"&gt;PWA&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>Don't use custom hooks as like global state</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Fri, 24 Jan 2020 17:06:36 +0000</pubDate>
      <link>https://dev.to/origamium/don-t-use-custom-hooks-like-global-state-dda</link>
      <guid>https://dev.to/origamium/don-t-use-custom-hooks-like-global-state-dda</guid>
      <description>&lt;p&gt;yes. look this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useInvalidHooks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ParentComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useInvalidHooks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`parent: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InnerComponent&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;InnerComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useInvalidHooks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`children: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;hai&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click button in &lt;code&gt;InnerComponent&lt;/code&gt;. And if you think update ParentComponent &lt;code&gt;const [state] = useInvalidHooks&lt;/code&gt;, its wrong.&lt;br&gt;
This code is equivalent to the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ParentComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`parent: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InnerComponent&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;InnerComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`children: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;hai&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it's obvious.&lt;/p&gt;

&lt;p&gt;custom hooks may misunderstanding: custom hooks is globally... isn't it.&lt;br&gt;
custom hooks is &lt;strong&gt;locally&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you need global state on custom hooks, use context api. or redux...&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>beginners</category>
    </item>
    <item>
      <title>そのContext呼び出しはProvider以下にあると保証できますか？</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Fri, 24 Jan 2020 16:31:49 +0000</pubDate>
      <link>https://dev.to/origamium/context-provider-3b90</link>
      <guid>https://dev.to/origamium/context-provider-3b90</guid>
      <description>&lt;h1&gt;
  
  
  はい
&lt;/h1&gt;

&lt;p&gt;reactのcontextは便利です。Reduxキラーとして君臨し、多くの開発者を苦しめてきました。特にhooksが登場してからというもの、&lt;code&gt;useContext()&lt;/code&gt;によりその利便性はさらに高くなりました。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DataContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;あるいは&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;DataContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="cm"&gt;/* render something */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;DataContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;さて、このとき&lt;code&gt;DataContext.Provider&lt;/code&gt;以下でこれらが呼び出されることを保証できるでしょうか？結論から言うとできません。TypeScriptにおいても同様です（そりゃそうだ）&lt;br&gt;
ちなみに、ProviderがなければcreateContextのデフォルト値がそのまま利用できます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DataContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;hai&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;haijanaiga&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;hai&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DataContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hai&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// its equally `&amp;lt;h1&amp;gt;haijanaiga&amp;lt;/h1&amp;gt;`&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;しかし、たいていの場合において&lt;code&gt;&amp;lt;Context.Consumer /&amp;gt;&lt;/code&gt;および&lt;code&gt;useContext()&lt;/code&gt;はProvider以下で呼びたいことが殆どでしょう。&lt;br&gt;
しかし、Reactはこのときエラーになってくれません。デフォルト値が存在するためです。&lt;br&gt;
また、ほとんどの場合開発時にのみ問題になりうるものですから、そのときにエラーになってくれればよいものです。すると、次のようなコードを書くことになるでしょう…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;SomeContextType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;hai&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DataContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;SomeContextType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DataProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;DataContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useDataCtx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;SomeContextType&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DataContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Not children of DataContext.Provider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;このとき、&lt;code&gt;&amp;lt;DataProvider state={{hai: ""}}&amp;gt;&lt;/code&gt;がない状態で&lt;code&gt;useDataCtx()&lt;/code&gt;が呼び出されても、適正にエラーが送出されるため、健全性が高まると言えます。&lt;br&gt;
あるいは、非同期処理を利用などの理由でわざと&lt;code&gt;undefined&lt;/code&gt;を挿入しているとしても、&lt;code&gt;if (typeof ctx === "undefined")&lt;/code&gt;などで代替し、読み込みの状態については&lt;code&gt;null&lt;/code&gt;を注入することもできます。もっとも、nullを注入するような行為は健全性に欠けますが…&lt;br&gt;
単純に考えましょう。読み込み中であるstateたとえば&lt;code&gt;{suspending: true}&lt;/code&gt;をProviderに注入する方法が効きます。&lt;/p&gt;

&lt;p&gt;ところであなたのContextは健全ですか？&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>react</category>
    </item>
    <item>
      <title>custom hooksをグローバル変数みたいに扱わないで</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Thu, 23 Jan 2020 09:43:51 +0000</pubDate>
      <link>https://dev.to/origamium/custom-hooks-2cpi</link>
      <guid>https://dev.to/origamium/custom-hooks-2cpi</guid>
      <description>&lt;p&gt;english: &lt;a href="https://dev.to/origamium/don-t-use-custom-hooks-like-global-state-dda"&gt;https://dev.to/origamium/don-t-use-custom-hooks-like-global-state-dda&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;はい、まずこのコードを見てください。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useInvalidHooks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ParentComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useInvalidHooks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`parent: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;InnerComponent&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;InnerComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useInvalidHooks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`children: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;hai&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;このとき、&lt;code&gt;InnerComponet&lt;/code&gt;のbuttonを押下したさい、その親である&lt;code&gt;ParentComponent&lt;/code&gt;で&lt;code&gt;state&lt;/code&gt;の変更と更新を期待していると、ものの見事に打ちのめされます。変更されません。&lt;br&gt;
経験豊かなReactエンジニアにはその理由はすぐわかると思います。&lt;/p&gt;

&lt;p&gt;はい、理由は生成されたhooksは他のhooksの状態とは完全に別ですからです。私はこれに2時間ぐらい悩みましたが…&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>webpack-dev-serverでdisableHostCheckを使うのはもうやめろ</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Mon, 23 Dec 2019 09:41:34 +0000</pubDate>
      <link>https://dev.to/origamium/webpack-dev-server-disablehostcheck-4am</link>
      <guid>https://dev.to/origamium/webpack-dev-server-disablehostcheck-4am</guid>
      <description>&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;DO NOT USE &lt;code&gt;disableHostCheck&lt;/code&gt;. because its potentially vulnerable.&lt;br&gt;
USE &lt;code&gt;host: "0.0.0.0&lt;/code&gt; and &lt;code&gt;useLocalIp&lt;/code&gt;. its safe, for now.&lt;/p&gt;

&lt;p&gt;ハローこんにちは。&lt;code&gt;disableHostCheck: true&lt;/code&gt;を使うのをやめろ。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;disableHostCheck&lt;/code&gt;を使うのにはだいたい理由があって、たとえばiPhoneからPC上のlocalhostで動いているサイトを見たいという理由で&lt;code&gt;disableHostCheck&lt;/code&gt;を&lt;code&gt;true&lt;/code&gt;にしたりしてアクセスしたりします。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasknu1bpr2ktglpox06a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasknu1bpr2ktglpox06a.png" alt="Alt Text" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[マシン名].local:[ポート番号]&lt;/code&gt;でアクセスするのはiPhoneを使った開発ではよく見る光景ですね。このとき&lt;code&gt;disableHostCheck&lt;/code&gt;はだいたいInvalid Host headerを回避するために使います。&lt;/p&gt;

&lt;p&gt;しかし、&lt;code&gt;disableHostCheck&lt;/code&gt;を有効にするとDNS rebinding attack脆弱性を抱えてしまいますし、実際に &lt;strong&gt;webpack-dev-serverのdocumentationでも非推奨&lt;/strong&gt; の方法となっています。&lt;br&gt;
代わりに今の所、&lt;code&gt;useLocalIP: true&lt;/code&gt;を使えば解決することができます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;devServer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.0.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;useLocalIp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;host: "0.0.0.0"&lt;/code&gt;はないと動かないので注意。&lt;br&gt;
この方法を使えばdisableHostCheckを回避できます。自分のローカルIPアドレスを使ってやればアクセスできるので、ネットワークによってURLは変更されますが。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F555ylx9nn1jyst6umkxs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F555ylx9nn1jyst6umkxs.png" alt="Alt Text" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>webpack</category>
    </item>
    <item>
      <title>Houdini初心者のためのローレンツ方程式の数値解導出とビジュアライズ</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Wed, 18 Dec 2019 18:32:23 +0000</pubDate>
      <link>https://dev.to/origamium/houdini-ig3</link>
      <guid>https://dev.to/origamium/houdini-ig3</guid>
      <description>&lt;p&gt;&lt;a href="https://adventar.org/calendars/3974" rel="noopener noreferrer"&gt;CPSLab Advent Calendar 2019&lt;/a&gt; 20日目の記事です。&lt;/p&gt;

&lt;p&gt;みなさんは &lt;strong&gt;プロシージャル（手続き的）&lt;/strong&gt; な3Dモデリングの経験があるでしょうか。この記事はプロシージャルモデリングの手法でローレンツ方程式の計算の過程を解説します。&lt;/p&gt;

&lt;h1&gt;
  
  
  プロシージャルな手法
&lt;/h1&gt;

&lt;p&gt;ググれば腐るほど詳細が出てきますが、ソフトウェアエンジニアの方々ならば「プロシージャルな手法」という言葉に魅了的な響きを感じるものがあるのではないでしょうか？&lt;br&gt;
あまりピンとこなかった方にピンとこないであろう解説をすると、 &lt;strong&gt;（数学的な意味も含む）関数の組み合わせ&lt;/strong&gt; によってモデルを生成するという手法です。&lt;/p&gt;

&lt;p&gt;これを実用的なものに落とし込んだものが、プロシージャルな手法でマテリアル（テクスチャ）を作成するSubstance Designer、そして今回紹介・使用するHoudiniです。&lt;/p&gt;
&lt;h1&gt;
  
  
  Houdiniとは？
&lt;/h1&gt;

&lt;p&gt;プロシージャルモデリングを恐らく最も積極的に行っているソフトウェアであり、水や煙、炎におけるビジュアルエフェクトについて強力なソリューションを有しているソフトウェアです。&lt;br&gt;
試用については無料であり、開発元の&lt;a href="https://www.sidefx.com/" rel="noopener noreferrer"&gt;SideFXのページ&lt;/a&gt;からApprentice版を無期限かつ無料利用することができます（制限はありますが、今回は全く問題にならないため省略します）。&lt;/p&gt;

&lt;p&gt;インストールすると最上位ライセンスであるHoudini FXなど全部のライセンスバージョンがインストールされますが、起動するのはHoudini Apprenticeです。&lt;/p&gt;
&lt;h1&gt;
  
  
  今回の目標
&lt;/h1&gt;

&lt;p&gt;次のようなモデルが出力されることをゴールとしています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3y28hpcixxqawoh6dbox.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3y28hpcixxqawoh6dbox.jpg" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;よく目にするローレンツ方程式の図ですね。今回はローレンツ方程式が表現する状態を求めることまでを目標にします。ローレンツ方程式についてはググればたくさん出てきますが、難しいことはさておいて以下の方程式で与えられます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5u3scmxo19e39818aje.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5u3scmxo19e39818aje.png" alt="Lorentz attractor equation" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Houdiniことはじめ
&lt;/h1&gt;

&lt;p&gt;まず、Houdiniの細かいUIはさておくとして、プロシージャルモデリングを実施するにあたりHoudiniはノードベースのエディタを利用します。その中で今回利用するノードは大きく分けて &lt;strong&gt;SOP(Surcace OPerator&lt;/strong&gt; 、 &lt;strong&gt;Wrangle&lt;/strong&gt; 、&lt;strong&gt;SOP Solver&lt;/strong&gt; の3種類です。また、Houdiniのプログラミング言語として &lt;strong&gt;VEXpression&lt;/strong&gt; を利用します。&lt;br&gt;
恐ろしいことにHoudiniではこれ以外にもノードの種類があり、プログラミング言語においてはHScript(deprecated)やPython、C++を使う機会も存在しますが、今回は使いません。&lt;/p&gt;
&lt;h2&gt;
  
  
  SOP
&lt;/h2&gt;

&lt;p&gt;まず先にSOPから説明します。Surface OPeratorの通り、サーフェスに対して行う処理です。が、頂点や辺、点に対してもオペレーションが行われます。これらはそれらを作成する、あるいは変更を加えるものがあります。また、出力や状態を司るものまで多種多様揃っています。まるでRxのようです&lt;/p&gt;

&lt;p&gt;基本的に、ルートのノードでは作業を行わず、 &lt;strong&gt;Geometry&lt;/strong&gt; ノード以下で行います。この関係はディレクトリ構成とよく似ています…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ulbgzpjxpjfahcp4xlu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ulbgzpjxpjfahcp4xlu.png" alt="Geometry Node" width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ノードエディタ（デフォルトでは画面右下）にフォーカスした状態でTabキーを押下し、&lt;code&gt;geo&lt;/code&gt;まで入力するとGeometry SOPが候補に上がります。今回はこれを利用します。&lt;br&gt;
Enterを2回押下し、ノードを配置します。&lt;br&gt;
そして&lt;code&gt;geo1&lt;/code&gt;ノードをダブルクリックし、ノードの中に入ります。これはサブウィンドウ右上の戻る進むボタンからいつでも上の階層あるいは下の階層に戻ることができ、さながらディレクトリのようです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4hmjubyoyrcuknd3500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4hmjubyoyrcuknd3500.png" alt="Platonic Solid SOP" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;たとえば正多面体を生成するPlatonic Solid SOPです。こちらは&lt;code&gt;geo1&lt;/code&gt;ノードに入った状態でふたたびTabキーを押下し、&lt;code&gt;platonic&lt;/code&gt;まで押下すると候補が出てくるので、やはり同じように配置します。&lt;/p&gt;

&lt;p&gt;このSOPのふるまいはデフォルトの画面右上のアトリビュートエディタから変更可能です。たとえば、デフォルトでは&lt;code&gt;Solid Type&lt;/code&gt;が&lt;code&gt;Tetrahedron（正三角錐）&lt;/code&gt;ですが、画像では&lt;code&gt;Dodecahedron（十二面体）&lt;/code&gt;に変更しています。この他にもPlatonicではありませんが、サッカーボールやUtah Teapodなどが選択できます（Utah Teapodは有名ですよね！）&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydy7a0gntl9rdeksti9r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydy7a0gntl9rdeksti9r.png" alt="Utah Teapod" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;では、Utah TeapodからSOPの強力な機能を見ていきましょう。Platonic Solid SOPにおけるUtah Teapodは（恐らく）NURBSサーフェスの集合ですが、これをポリゴンに変更してみましょう。&lt;br&gt;
手法はおそろしく簡単で、Platonic SolidからConvert SOPノードに接続するだけです。Convert SOPを作成し、Platonic SolidからConvertへ接続し、Convertノードの一番右側、マウスホバー時に青色になる部分をクリックすればポリゴン化されたUtah Teapodが出現するはずです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmyennygz3vdkqwo05g5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmyennygz3vdkqwo05g5z.png" alt="Plug to Convert SOP" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;あっというまです…このとき、Convert SOPにフォーカスした状態でアトリビュートエディタのU, Vの値を変更すると、それぞれの方向についてポリゴンがどれほどの密度になるのかを変化させることができます。&lt;/p&gt;

&lt;p&gt;このとき、ノードを削除あるいはバイパス（ノード左の黄色になる部分を有効）にすれば瞬時にそのオペレーションは無視された状態のオブジェクトが生成されます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgaubzaum5yuv650x6zdj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgaubzaum5yuv650x6zdj.png" alt="Node Bypass" width="568" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;また、数学的な側面も存在します。IsoSurface SOPでは、Implicit Surface（陰関数曲面） &lt;em&gt;注:正式な和訳を知りません…&lt;/em&gt; の描画が行えます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6egsv4jc4mijqpuvn1gh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6egsv4jc4mijqpuvn1gh.png" alt="IsoSurface SOP" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;デフォルトでは球が描画されます。アトリビュートエディタのImplicit Functionを見ると、球の描画に使われる&lt;code&gt;x^2 + y^2 + z^2 - 1 = 0&lt;/code&gt;の左辺がそれとなく表現されていますね！このままでは不便なポリゴンなので、Remesh SOPを用いるとメッシュが再構成されます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaqgyy6qsz4dgixer76o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaqgyy6qsz4dgixer76o.png" alt="Remesh SOP" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ほんの片鱗ですが、これがHoudiniの強力さのあらわれです。ほかにもたくさんの種類のSOPが存在し、それらは非破壊的に行われます…つまり、もとのオブジェクトに変更は一切かかっていないということです（いつでももとに戻せます！）&lt;/p&gt;

&lt;p&gt;そして、重要なSOPに、Group SOPが存在します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F83alpilixcnwnjpibzdp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F83alpilixcnwnjpibzdp.png" alt="Group SOP" width="800" height="1141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;これは要するにpointやedgeを選択したものを保存しておくSOPですが、この後のSOPなどでこのGroupを指定してそこだけ効果を適用する、などという器用なことが可能になります。この場合入力したサーフェスのpoint番号1から100までのポイントをGroup1として保存しています。&lt;/p&gt;
&lt;h2&gt;
  
  
  WrangleノードとVEXPression(VEX)
&lt;/h2&gt;

&lt;p&gt;WrangleノードはPoint Wrangle, Attribute Wrangleなど各種ありますが、どれもVEXpressionというプログラミング言語を利用したSOPです。種類によりますが、たとえばAttribute Wrangleはアトリビュートの調整を行うSOPです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7cij4vhcito33qa0qi3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7cij4vhcito33qa0qi3u.png" alt="Sin wave with wrangle" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;注：このままでは見づらいので、上記の図では線をポリゴンチューブにするWire SOPを利用しています&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;このサンプルのために、まずはLine SOPを作成し、アトリビュートのLengthを10に設定します。このノードをResampleノードに接続し、Lengthを0.01に設定します。そしてAttribute Wrangleに接続し、次のコードをアトリビュートエディタ内のコードエディタに記述します…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@P.x = 0;
@P.z = float(@ptnum) / 100;
@P.y = sin(radians(@ptnum));

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ソフトウェアエンジニアの方へ…セミコロンでの文の終端から、floatへの型キャスト、関数呼び出しなど、見慣れたオペレータ群が揃っていますね！&lt;/p&gt;

&lt;p&gt;セミコロンは文の終端にないとエラーになります。ご注意！&lt;/p&gt;

&lt;p&gt;しかし、暗黙的に利用されているアットマーク開始の変数たちにフォーカスする必要がありますね。まず、&lt;code&gt;@P&lt;/code&gt;が何なのかについて解説する必要があるでしょう。これはWrangleが処理しているポイントのひとつを指しており、x, y, zのプロパティを持っています。そして&lt;code&gt;@ptnum&lt;/code&gt;は現在のポイントの番号を指しています。&lt;/p&gt;

&lt;p&gt;これらをなんとなく理解するために、Attribute Wrangleにフォーカスし、メインの画面からGeometry Spreadsheetを開きます…そこは地獄のようです&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feou3exr5wubq892yst5c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feou3exr5wubq892yst5c.png" alt="Geometry Spreadsheet" width="800" height="1115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;落ち着いて見ていきましょう。&lt;code&gt;@P&lt;/code&gt;の持つ値が一覧として表示されています。これらをアトリビュートと呼び、これらの値に代入することでアトリビュートを変更しています。また、アトリビュートは任意にジオメトリに挿入することができます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f@amount = @ptnum;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;f&lt;/code&gt;は浮動小数点である&lt;code&gt;float&lt;/code&gt;を表しており、&lt;code&gt;float&lt;/code&gt;型として&lt;code&gt;amount&lt;/code&gt;を定義し&lt;code&gt;@ptnum&lt;/code&gt;の値を代入しています。これをAttribute Wangleに代入すると、Geometry Spreadsheetに&lt;code&gt;amount&lt;/code&gt;の項目が追加されていることに気がつくでしょう。これは値を保存し、後々のWrangleで利用したいときに便利です。&lt;/p&gt;

&lt;h2&gt;
  
  
  SOP Solver DOP
&lt;/h2&gt;

&lt;p&gt;SOP Solver DOPは特殊で、アニメーションにおいて（画面下のタイムラインに関することです）、前のフレームを参照して現在のフレームを作成するDOPとなっています。&lt;/p&gt;

&lt;p&gt;…いきなりDOPという言葉が出てきましたね。もう面倒になっているのであまり解説しませんが、Dynamic Operator nodeの略です。文字通りダイナミックに変化するものに対して使えるオペレータですが、私はこれ以外のDOPを知りません…&lt;/p&gt;

&lt;p&gt;たとえばsin波をアニメーションしてみましょう。先ほどのネットワークからWrangleを削除し、次のようにSOP Solverを配置します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foaa31f4d98mpmozf3ksx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foaa31f4d98mpmozf3ksx.png" alt="SOP Solver" width="368" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;そして、SOP Solverにダブルクリックし、SOP Solverの中に入ります。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu20jen1ovx6is1cwbuki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu20jen1ovx6is1cwbuki.png" alt="SOP Solver Network" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SOP Solverのネットワークは至極単純です。前のフレームを表す&lt;code&gt;Prev_Frame&lt;/code&gt;ノード、そしてSOP Solverにつないだ入力4つのノードです。&lt;/p&gt;

&lt;p&gt;今回は&lt;code&gt;Prev_Frame&lt;/code&gt;を主に利用します。&lt;code&gt;Prev_Frame&lt;/code&gt;にAttribute Wrangleを繋ぎ、次のコードを挿入します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@P.x = 0;
@P.y = sin(radians(@Frame*10 + 500 * @ptnum / 1000));
@P.z = float(@ptnum) / 100;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;そして、ウィンドウ左下の再生ボタンをクリックします。するとサイン波が横に移動している（ように見える）でしょう。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2q0s6hzfpyss68blanu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2q0s6hzfpyss68blanu.png" alt="Timeline view" width="800" height="67"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;青色の部分が計算（キャッシュ）済みの部分です。ここの部分については計算なしで再生できますが、より複雑な計算をSOP Solverで利用するとメモリが枯渇しがちです。&lt;/p&gt;

&lt;p&gt;もし計算が重くて、動かなくなってしまった場合、Escキーを押下することで計算をキャンセルできます。覚えておくと便利です。&lt;/p&gt;

&lt;h1&gt;
  
  
  さあ、ローレンツ方程式を計算しよう！
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Add SOPで始点を作成&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ft4hs2jsbkqolra4wk7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ft4hs2jsbkqolra4wk7.png" alt="Add SOP" width="800" height="746"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add SOPは何かと便利なものですが、ここではローレンツ方程式を計算するに当たり、始点をひとつ登録するだけのことをします。&lt;br&gt;
アトリビュートエディタでPointタブを開いた状態で、始点を0.1, 0.1, 0.1にし、チェックボックスを有効化して点を登録します。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;last Groupを作成する&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4klwp201fpfsdjr1y8hb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4klwp201fpfsdjr1y8hb.png" alt="Group SOP" width="800" height="943"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ここでは何も選択せず、group nameをlastにします。これで後ほどlast groupを利用することができます。今の所、中身は空っぽですが…&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Solver SOPを作成する&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Solver SOPを作成し、中に入り&lt;code&gt;Prev_Frame&lt;/code&gt;にAttribute Wrangleを作成します。このとき、Wrangleの&lt;strong&gt;Groupをlastに設定&lt;/strong&gt;します。これは"last" Groupにのみこの処理を行うという意味です。この効果は後ほど。&lt;/p&gt;

&lt;p&gt;そして、Wrangleは次のようにコードを記述します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;float dx(vector Point) {
    float p = 10.0;
    return p*(Point.y - Point.x);
}

float dy(vector Point) {
    float r = 28.0;
    return Point.x*(-Point.z + r) - Point.y;
}

float dz(vector Point) {
    float b = 8.0/3.0;
    return Point.x * Point.y - b * Point.z;
}

float dt = 0.01;

int newpointnumber = addpoint(geoself(), @P + set(dx(@P), dy(@P), dz(@P)) * dt);
setpointgroup(geoself(), "last", @ptnum, 0);
setpointgroup(geoself(), "last", newpointnumber, 1);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;関数の宣言と実装、返り値についてはここで語るまでもないでしょうが、念の為解説をします。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;float dx(vector Point) {
    float p = 10.0;
    return p*(Point.y - Point.x);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;この関数&lt;code&gt;dx()&lt;/code&gt;は&lt;code&gt;vector&lt;/code&gt; - つまり&lt;code&gt;x,y,z&lt;/code&gt;3つの座標(&lt;code&gt;float&lt;/code&gt;)を持つ型を受け取り、その値についてfloat型の値を返す関数です。中身の計算については、かつて上に示したローレンツ方程式の一式目とほぼ同様なことが伺えます。&lt;br&gt;
ローレンツ方程式については2式目、3式目についても同様の関数を作成します。 - これがこの処理の中核をなします。&lt;/p&gt;

&lt;p&gt;ですが、まだいくつかのことについても解説が必要ですね。&lt;br&gt;
&lt;code&gt;set()&lt;/code&gt;関数は与えられた&lt;strong&gt;引数の数にもとづいて&lt;/strong&gt; &lt;code&gt;vector2&lt;/code&gt;, &lt;code&gt;vector&lt;/code&gt;, &lt;code&gt;vector4&lt;/code&gt;, &lt;code&gt;matrix&lt;/code&gt;型の値を返す関数です。今回は3つの引数が与えられているため、&lt;code&gt;vector&lt;/code&gt;型の値が返ってきます。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;geoself()&lt;/code&gt;関数は処理している自分自身のジオメトリ番号を示しています。この場合ジオメトリは1つしかありませんから、&lt;code&gt;0&lt;/code&gt;です。そのため&lt;code&gt;geoself()&lt;/code&gt;の代わりに&lt;code&gt;0&lt;/code&gt;でも差し支えありません。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;addpoint()&lt;/code&gt;関数はジオメトリに文字通り点を追加し、追加された点の番号を返却します。返却された点番号は&lt;code&gt;int&lt;/code&gt;型です。&lt;/p&gt;

&lt;p&gt;ここで最も肝要なのは、&lt;code&gt;setpointgroup()&lt;/code&gt;関数です。これはpointをどのグループに属させるのかという選択の関数であり、引数は対象となるジオメトリ番号（*注:この関数は現状、0以外を受け取りません)、グループ名、ポイント番号、そして選択されている&lt;code&gt;1&lt;/code&gt;かされてないか&lt;code&gt;0&lt;/code&gt;をとります。&lt;/p&gt;

&lt;p&gt;ここで&lt;code&gt;@ptnum&lt;/code&gt;は現在処理しているポイントを指しており、これは"last"グループから非選択とします。そして、新しく生成されたポイントである&lt;code&gt;newpointnumber&lt;/code&gt;を選択としています。&lt;/p&gt;

&lt;p&gt;この"last" Group指定は重要です - このWrangleは最初に"last"グループに対して処理するという宣言をしました。"last" Groupが継続的に変化することによって、最後のポイントに対してのみ処理を行えるのです。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;経過確認&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ここまでの処理を終えたら、一旦上の階層にまで戻り、SOP Solverを可視状態にし、再生ボタンを押します。&lt;br&gt;
ローレンツ方程式が求まっていく様子が確認できると思います。&lt;/p&gt;

&lt;p&gt;tips: アニメーションが短すぎてよくわからない！と思ったら、Solver SOPにフォーカスし、アトリビュートエディタからSub Stepsを10にまで増やしてみましょう。1フレームにつき10回計算が行われるようになり、見かけ上光速になります。また、アニメーションの左下Global Animation OptionsからEndを1000程度にし、Applyすると1000フレームまでアニメートされます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2w2s6xlmqx5uub77bnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2w2s6xlmqx5uub77bnx.png" alt="Global Animation Options" width="800" height="978"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;そして、ある程度まで計算されたローレンツ方程式の結果を見てみましょう。うまくいけば次のようになっているはずです…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo3j4h431jjp9qwhbsm7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo3j4h431jjp9qwhbsm7z.png" alt="Numerical solution!" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;点群ですね！これは点群なので、「それらしい見た目」とはなっていません。点と点を結び、線にする必要があります。そこで、ふたたびAdd SOPの出番です！SOP Solverに新たにAdd SOPを接続し、アトリビュートエディタからPolygonsタブ&amp;gt;By Groupを選択すると、線分が作成されます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tbjxyx496xob9g6h9ew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tbjxyx496xob9g6h9ew.png" alt="Lorentz" width="800" height="790"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;線分になったからにはやりたい放題です - ここにPolywire SOPをつないでもよいし、Copy To Point SOPの第2入力に入れて、Sphereなどを第一引数に入れて点をもっと大きく描画することも可能です - これが私達のゴールです。&lt;/p&gt;

&lt;p&gt;ですが、もう少しあがいてみましょう。ここからはHoudini特有の「お作法」です。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;お作法&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;記述したWrangleの中に直書きの数値があったことに気づきましたか？これらをひとつのCONTROLLERというノードにまとめて一括で管理できるようにします。&lt;/p&gt;

&lt;p&gt;AddやSolver SOPと同じ階層にNullノードを作成します。名前を&lt;code&gt;CONTROLLER&lt;/code&gt;とします。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pvfek8mwq0iykrf1lgh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pvfek8mwq0iykrf1lgh.png" alt="Null Node" width="800" height="902"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;アトリビュートエディタのヘッダにある歯車アイコンをクリックし、Edit Parameter Interfaceを選択します。すると次のウィンドウが表示されます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Femfrjbzyj7zxptii9yca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Femfrjbzyj7zxptii9yca.png" alt="Edit Parameter Interface Window" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;左側のペインからFloatを選択し、ドラッグ・アンド・ドロップで右側のペインに移動します。これを4回繰り返しましょう。&lt;/p&gt;

&lt;p&gt;そして右側ペインから上から順に&lt;code&gt;p&lt;/code&gt;, &lt;code&gt;r&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, &lt;code&gt;dt&lt;/code&gt;と命名します。このとき、&lt;code&gt;dt&lt;/code&gt;は値が大きすぎると数値解が発散してしまうため、Rangeにチェックを入れて&lt;code&gt;0.001&lt;/code&gt;から&lt;code&gt;0.01&lt;/code&gt;とし、両側の鍵のボタンを押します。&lt;/p&gt;

&lt;p&gt;すべてが済んだら"Accept"で変更を保存しましょう。&lt;/p&gt;

&lt;p&gt;次のようになっているはずです…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rl947i4bhd3v2qmqnn0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rl947i4bhd3v2qmqnn0.png" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;これにそれぞれ、p=10, r=28, b=2.6666666667を挿入します。dtは0.01にします。&lt;/p&gt;

&lt;p&gt;そして、SOP SolverのWrangleコードを次のように変更し、コードエディタの右側にあるスライダーと+アイコンを一緒にしたようなボタンを押します。すると、コード下部にパラメータが追加されます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;float dx(vector Point) {
    float p = ch("p");
    return p*(Point.y - Point.x);
}

float dy(vector Point) {
    float r = ch("r");
    return Point.x*(-Point.z + r) - Point.y;
}

float dz(vector Point) {
    float b = ch("b");
    return Point.x * Point.y - b * Point.z;
}

float dt = ch("dt");

int newpointnumber = addpoint(geoself(), @P + set(dx(@P), dy(@P), dz(@P)) * dt);
setpointgroup(geoself(), "last", @ptnum, 0);
setpointgroup(geoself(), "last", newpointnumber, 1);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkil78wj2axm0e4xg28eu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkil78wj2axm0e4xg28eu.png" alt="Alt Text" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;一旦CONTROLLERノードまで戻り、pの値を右クリックして「Copy Parameter」を実行します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4fpx8x1kkjeakjns6v7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4fpx8x1kkjeakjns6v7.png" alt="Alt Text" width="800" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ふたたびSOP SolverのWrangleノードに戻り、パラメータPの値を一旦殻にしてから右クリックし、今度は「Paste Relative References」をクリックします。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ilhcfaypwzhw2tkoji5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ilhcfaypwzhw2tkoji5.png" alt="Alt Text" width="800" height="605"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;すると&lt;code&gt;ch("../../../../CONTROLLER/p")&lt;/code&gt;が挿入されます。まさにrelative referencesです。これはCONTROLLER(Null)ノードのパラメータを参照しています。同様に他のパラメータについても同じことを行いますが、面倒なのでこれをコピペし、&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ch("../../../../CONTROLLER/r")&lt;/code&gt;&lt;br&gt;
&lt;code&gt;ch("../../../../CONTROLLER/b")&lt;/code&gt;&lt;br&gt;
&lt;code&gt;ch("../../../../CONTROLLER/dt")&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;と言った具合に推定できるものはとっとと書いてしまいましょう。さいわいなことに、補完が効いてくれます。&lt;/p&gt;

&lt;p&gt;もう一度実行してみましょう…何も変わりません。では、CONTROLLERからパラメータのスライダーを色々いじってみて、ローレンツ方程式がどのように変化するのかを観察してみましょう…これからは遊びの時間です！自由にローレンツ方程式の係数を変えて、様々な形に表情を変えていく様を見ましょう！&lt;/p&gt;

&lt;h2&gt;
  
  
  補足
&lt;/h2&gt;

&lt;p&gt;説明が完全に入り込む隙間がありませんでしたが、最後の解説としてVEXについて説明せねばならないでしょう。「なぜローレンツ方程式をSOP Solverを経由して解かなければならなかったのか？」&lt;br&gt;
答えはVEXが完全に並行に実行されるプログラミング言語なためです。これはある点あるいはエッジの前後を参照できないということを指しており、これがローレンツ方程式のビジュアライズにとっては非常にネックとなってしまいます…ローレンツ方程式のビジュアライズには、前のポイントの情報が必要なのですから。そのため、今回のローレンツ方程式のビジュアライズはVEXのパワーを活かしきれていないということです…&lt;/p&gt;

&lt;p&gt;そう、VEXはとても強力な言語です。意識せず並行処理が行われ、SIMDなどの支援による高速な実行が期待できます。ですから、可能な限りVEXで完結するような処理を考えるべきです。&lt;/p&gt;

&lt;p&gt;なお、無視していましたがPythonのノードが用意されており、Pythonでとっととローレンツ方程式を描写することもできます。今回はもうやりませんが。何度も言いますがVEXで書けることはVEXで書くべきなのです。&lt;/p&gt;

&lt;h2&gt;
  
  
  おわりに
&lt;/h2&gt;

&lt;p&gt;この動画に助けられました: &lt;a href="https://www.youtube.com/watch?v=saA6-edb-OE" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=saA6-edb-OE&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Houdiniは3Dデザインを主としており、上記の特性を利用してアルゴリズミックなデザインも可能になります…フィボナッチ数を用いて花をそれらしく表示したり、マンデルブロ集合を3Dに拡張したものを表示したり…またその特性から無機物と自然物のモデリングも得意です。そして、忘れないでおいてほしいのが、Houdiniは炎や水、破壊の表現も得意です…これらの組み合わせはとても強力なものばかりです。Houdiniワールドは広い。この荒野をもっと旅する気分になったなら、Appertanceライセンスでいつまでも冒険を続けることが可能です…&lt;/p&gt;

&lt;p&gt;ようこそ、プロシージャルモデリングの世界へ！&lt;/p&gt;

</description>
      <category>houdini</category>
      <category>japanese</category>
      <category>3d</category>
    </item>
    <item>
      <title>package.jsonの各種要素を読み込みたい！</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Wed, 24 Jul 2019 18:53:10 +0000</pubDate>
      <link>https://dev.to/origamium/package-json-1626</link>
      <guid>https://dev.to/origamium/package-json-1626</guid>
      <description>&lt;p&gt;ラーメン 今日食べたものです。package.jsonに書かれたデータが欲しいことが往々にして存在します。たとえば&lt;code&gt;version&lt;/code&gt;です。普段から&lt;code&gt;npm version&lt;/code&gt;コマンドを利用するように意識していると、やはりどうしてもアプリケーション内でpackage.json内の&lt;code&gt;version&lt;/code&gt;を読み込んで表示したり、&lt;code&gt;console.error&lt;/code&gt;を繰り出す際に&lt;code&gt;version&lt;/code&gt;も併記してSentryなどのエラー監視ツールなどの補助情報として利用し、問題の絞り込みをしてみたくなるものです。&lt;/p&gt;

&lt;h2&gt;
  
  
  Node.js
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;process.env.npm_package_version&lt;/code&gt;を呼び出せばよい。かんたん&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Application
&lt;/h2&gt;

&lt;p&gt;ひとくちにWeb Applicationといってもなんか世界が広すぎて解説しきれないので2つの手法を提示する。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;package.json&lt;/code&gt;を読み込む
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ES6であれば次のように読み込める。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;packageJson&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../package.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;packageJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ただし、&lt;code&gt;src&lt;/code&gt;以下のディレクトリしか読み込みのみを許可されている場合はpackage.jsonを直接読み込むことができない。対処法としてはsymbolic linkを貼ってやればよい。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; package.json src/package.alias.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;これで次のように読み込める。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;packageJson&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./package.alias.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;packageJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;create-react-appの場合
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;そもそもpackage.jsonを読み込んでしまうのは中々穏やかではない（気がする）。create-react-appは最初から色々揃っており、&lt;code&gt;.env&lt;/code&gt;に次のように記載すればよい。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REACT_APP_VERSION=$npm_package_version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;すると&lt;code&gt;process.env.REACT_APP_VERSION&lt;/code&gt;として読み込みが可能である。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;おっと、これはWindowsでは動きませんよ!&lt;/strong&gt;&lt;br&gt;
このコードをwindowsでビルドしてしまうと、&lt;code&gt;process.env.REACT_APP_VERSION&lt;/code&gt;はバージョン情報を出さず、&lt;code&gt;$npm_package_version&lt;/code&gt;と表示してしまいます。困りましたね。&lt;/p&gt;

&lt;p&gt;Windowsでのnpmの環境変数の読み込みは次の形式となります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REACT_APP_VERSION=%npm_package_version%
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;しかしこれではmacOS, Linuxでうまく読み込めません。&lt;/p&gt;

&lt;p&gt;解決方法は、上記の.envのやり方を諦めてpackage.alias.jsonを読み込むか、泥臭い方法で頑張るかです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REACT_APP_VERSION_UNIX=$npm_package_version
REACT_APP_VERSION_WIN=%npm_package_version%
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REACT_APP_VERSION_WIN&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%npm_package_version%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REACT_APP_VERSION_UNIX&lt;/span&gt; 
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REACT_APP_VERSION_WIN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;泥臭いですがこれでWindows, macOS, Linuxどれでも&lt;code&gt;version&lt;/code&gt;情報を読み込むことができました。こんなことするぐらいならpackage.jsonをimportした方が良い気もしますが。&lt;/p&gt;

&lt;h1&gt;
  
  
  他にもnpmの環境変数が欲しい？
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;process.env&lt;/code&gt;には様々な情報が含まれています。パッケージ名を含む&lt;code&gt;npm_package_name&lt;/code&gt;、ライセンス情報を含む&lt;code&gt;npm_package_license&lt;/code&gt;等。各自見てください。全部紹介する気にはなりません。とはいえWeb開発にはpackage.jsonの中身さえ読めれば十分とは思います。&lt;/p&gt;

</description>
      <category>nodejsjavascript</category>
    </item>
    <item>
      <title>ReactとElectron間のデータの送受信の手法と一例</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Mon, 01 Oct 2018 14:50:46 +0000</pubDate>
      <link>https://dev.to/origamium/reactelectron-2gdo</link>
      <guid>https://dev.to/origamium/reactelectron-2gdo</guid>
      <description>&lt;h1&gt;
  
  
  注意！
&lt;/h1&gt;

&lt;p&gt;この記事内のいくつかの項目はoutdatedになりました。特に、&lt;code&gt;remote.require&lt;/code&gt;は非推奨です。&lt;/p&gt;

&lt;p&gt;バーチャルユーチューバーです。皆さんもバーチャルユーチューバーですか？&lt;/p&gt;

&lt;p&gt;前回の&lt;a href="https://dev.to/origamium/create-reactelectron-application-in-quickly--36nl"&gt;React+Electronアプリを作る話&lt;/a&gt;ではアプリを作るまでの事しか話しませんでした。そして、React及びRedux上で物事がだいたい済むのならば、ElectronやNode.jsについて深く思い悩むこともないでしょう。&lt;br&gt;&lt;br&gt;
しかし、Electronでアプリケーションを作りたいのならば、Node.jsおよびその上で動作するパッケージを使用したいことや、Electron上で取得したデータをReact上で表示したい、という望みがあるはずです。&lt;br&gt;
ここで問題になるのは、そのElectron-メインプロセス-とReact+Redux-レンダラプロセス-の間をどのように処理するか、についてです。  &lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;code&gt;remote.require&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;次に示すコードは、レンダラプロセスで使用している部分です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// レンダラプロセス&lt;/span&gt;
&lt;span class="c1"&gt;//@flow&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;remote&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;electron&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;remote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;electron&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default &lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAppPath&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;//アプリケーションの実行場所が絶対パスとして返ります&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;remote.require&lt;/code&gt;はレンダラプロセスで利用可能な&lt;code&gt;require&lt;/code&gt;の変わりだと思えば十分です。内部的にはinter-process communication (IPC)を利用してメインプロセスのメソッドを呼び出しており、最もシンプルにメインプロセスとのやり取りが可能です。&lt;br&gt;
基本的に、シリアライズ可能なデータであれば受け渡しが可能です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// レンダラプロセス&lt;/span&gt;
&lt;span class="c1"&gt;//@flow&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;remote&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;electron&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;remote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;electron&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;remote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default &lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAppPath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/internet.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;googlePublicDns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8:8.8.8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;code&gt;ipcMain&lt;/code&gt;、&lt;code&gt;ipcRenderer&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;ipcMain&lt;/code&gt;と&lt;code&gt;ipcRenderer&lt;/code&gt;はそれぞれEvent-Drivenな方策でメインプロセスとレンダラプロセスのデータの受け渡しを可能にする機能です。基本的な使い方は&lt;a href="https://electronjs.org/docs/api/ipc-main" rel="noopener noreferrer"&gt;Electron ipcMain&lt;/a&gt;のドキュメントに載っていますが、実際に使用するとなると（データフローをすべてredux上で済ませたいという気持ちがあるため）reduxとそのmiddlewareを利用した上で&lt;code&gt;ipcRenderer&lt;/code&gt;を利用する場合があります。&lt;br&gt;
少し複雑になりますが、&lt;code&gt;redux-saga&lt;/code&gt;を用いて&lt;code&gt;ipcRenderer&lt;/code&gt;を利用した例を次のコードに示します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// レンダラプロセス&lt;/span&gt;
&lt;span class="c1"&gt;// @flow&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;eventChannel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;END&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;redux-saga&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;take&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux-saga/effects&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ipcRenderer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;electron&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ipc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;eventChannel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emit&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;ipcRenderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;asynchronous-reply&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EVENT_RECEIVED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}});&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ipc connection disconnected with unknown error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// redux-sagaのrootsagaで1度だけ呼び出す&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ipc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;eventChannel&lt;/code&gt;はイベントエミッターを監視するのによく使用されます。&lt;code&gt;emit =&amp;gt; {}&lt;/code&gt;の中でリスナーを実装し、&lt;code&gt;emit&lt;/code&gt;でactionをdispatchすることができます。&lt;br&gt;
本来であればoncloseかなにかが送信された時点で&lt;code&gt;emit(END)&lt;/code&gt;を利用しイベントが終了したことをsagaに通知すべきですが、ipcRendererには無いので無視します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// メインプロセス&lt;/span&gt;
&lt;span class="nx"&gt;ipcMain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;asynchronous-message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints "ping"&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;asynchronous-reply&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pong&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;今回の場合、&lt;code&gt;asynchronous-message&lt;/code&gt;という名前のついたイベントがレンダラプロセスから送信された場合、メインプロセスは&lt;code&gt;asynchronous-reply&lt;/code&gt;イベントを返送し、データとして&lt;code&gt;'pong'&lt;/code&gt;を返送するようにしています。勿論、イベント名は何でもよく、レンダラプロセスとメインプロセス側で名前さえ一致していればよいです。&lt;br&gt;
そして、やはりシリアライズ可能なものであれば何であれ送受信可能です。&lt;/p&gt;

&lt;p&gt;試しに、レンダラプロセスの適当な場所で&lt;code&gt;'asynchronous-message'&lt;/code&gt;イベントを投げてみましょう。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// レンダラプロセス&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ipcRenderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;electron&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ipcRenderer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sending...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;ipcRenderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;asynchronous-message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ping&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;成功しているならば、コンソールは次のように表示されているでしょう。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Finzbd4ep81oj301nerm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Finzbd4ep81oj301nerm0.png" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;code&gt;WebContents.send&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;ipcMain&lt;/code&gt;のドキュメンテーションにレンダラプロセスに一方的に送信するメソッドがないことに気付きましたか？&lt;br&gt;
レンダラプロセスからメインプロセスへ一方的に送信しまくることはできますが、&lt;code&gt;ipcMain&lt;/code&gt;では基本的に「返送」しかできませんでした。&lt;br&gt;
メインプロセスからレンダラプロセスに何かを一方的に送信しまくりたいときもあります。その時は、&lt;code&gt;WebContents.send&lt;/code&gt;を用います。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// メインプロセス&lt;/span&gt;
&lt;span class="c1"&gt;// BrowserWindowのインスタンスmainWindowがあることを前提にしています&lt;/span&gt;
&lt;span class="nx"&gt;mainWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;asynchronous-message-from-love&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yeah&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
8&lt;/p&gt;

&lt;p&gt;ここまで読んできたならもう分かると思いますが、&lt;code&gt;"asynchronous-message-from-love"&lt;/code&gt;イベントを送信しています。これを受信するには先程のipcRendererの実装を使い回せばよいだけです。&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;code&gt;WebContents.executeJavaScript&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;これはかなり直球的なやり方です。見たままのコードが実行されます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// メインプロセス&lt;/span&gt;
&lt;span class="c1"&gt;// BrowserWindowのインスタンスmainWindowがあることを前提にしています&lt;/span&gt;
&lt;span class="nx"&gt;mainWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeJavascript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;console.log('yeah')&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;このコードが実行されると、レンダラ側のコンソールに&lt;code&gt;yeah&lt;/code&gt;が表示されます。文字列を組み合わせることで、最強のコード実行が可能です。ただし、&lt;code&gt;eval&lt;/code&gt;と同様、セキュリティ的な危うさもあるため、基本的にはハードコートした文字列の組み合わせのみで&lt;code&gt;executeJavascript&lt;/code&gt;を実行すべきです。&lt;/p&gt;

&lt;h1&gt;
  
  
  conclusion
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;レンダラプロセスでは&lt;code&gt;remote.require&lt;/code&gt;、&lt;code&gt;ipcRenderer&lt;/code&gt;を利用すればよい&lt;/li&gt;
&lt;li&gt;メインプロセスでは&lt;code&gt;webContents.send&lt;/code&gt;、&lt;code&gt;ipcMain&lt;/code&gt;、&lt;code&gt;webContents.executeJavasSript&lt;/code&gt;を利用すればよい&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;おわり&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>electron</category>
      <category>japanese</category>
    </item>
    <item>
      <title>なぜreducerで副作用を起こしてはならないか</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Wed, 25 Jul 2018 14:02:03 +0000</pubDate>
      <link>https://dev.to/origamium/redux-10j5</link>
      <guid>https://dev.to/origamium/redux-10j5</guid>
      <description>&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;reducerで副作用を起こすと、最悪の場合、コンポーネントのチューニングが不可能になる&lt;/p&gt;

&lt;h1&gt;
  
  
  本題
&lt;/h1&gt;

&lt;p&gt;こんにちは。まずこのようなコードがありました。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aka&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;pushAka&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aka&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;このインスタンスをreducerで管理したい。そんなことありますよね。たとえば次のように…（redux-actionsを暗黙的に使用している点はご容赦ください）&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Donald Trump&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;handleActions&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ADD_AKA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pushAka&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aka&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;これは、特に何も考えなければ、とりあえずはうまく動きます。しかし、&lt;a href="https://redux.js.org/introduction/three-principles" rel="noopener noreferrer"&gt;Reduxの3つの基本概念&lt;/a&gt;である大前提&lt;strong&gt;副作用を起こしてはならない&lt;/strong&gt;という点において、間違っています。&lt;br&gt;&lt;br&gt;
問題は&lt;code&gt;Account&lt;/code&gt;クラスの&lt;code&gt;pushAka(name)&lt;/code&gt;メソッドにあります。結局のところ、これは&lt;strong&gt;&lt;em&gt;自分自身のメンバ変数を変更した上で自分自身を返している&lt;/em&gt;&lt;/strong&gt;という事そのものに問題があります。しかし、今の所うまく動きます。&lt;br&gt;&lt;br&gt;
&lt;a href="https://stackblitz.com/edit/reducer-not-pure-anti-pattern" rel="noopener noreferrer"&gt;この時点でのStackblitzのサンプルです&lt;/a&gt;。  &lt;/p&gt;

&lt;p&gt;さて、今の所は動いています。すでに大問題ですが、ここから取り返しのつかないことが起きてきます。&lt;br&gt;&lt;br&gt;
Reactは高速ですが、それでもチューニングが必要になる場合が多々あります。コンポーネントの無駄な再レンダリングを防止するために、状況に合わせて主に以下の3つのチューニングが行われます。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;componentShouldUpdate(prevState, nextState)&lt;/code&gt;の使用&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;React.Component&lt;/code&gt;ではなく&lt;code&gt;React.PureComponent&lt;/code&gt;を使用&lt;/li&gt;
&lt;li&gt;Stateless Functional Componentsでは&lt;code&gt;recompose/pure&lt;/code&gt;,&lt;code&gt;recompose/onlyUpdateForKeys&lt;/code&gt;を使う&lt;/li&gt;
&lt;li&gt;自分でpure HoCを書く&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;さて、この場合でもチューニングを行ってみましょう。今回は先程のサンプルにおいては&lt;code&gt;components/AkaList.js&lt;/code&gt;がStateless Functional Componentsですから、試しに&lt;code&gt;pure&lt;/code&gt;を使ってコンポーネントのチューニングを行ってみます。単に次のように書き換えるだけです…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pure&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;recompose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AkaList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aka&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;pure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AkaList&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;recomposeの&lt;code&gt;pure&lt;/code&gt;でコンポーネントの再レンダリングを抑えようとしています(例として少し極端ですが、ご容赦ください。時間がなかったんだ でも動かないサンプルがこちらにある)  &lt;/p&gt;

&lt;p&gt;すると、リストがあるはずの場所に、何もレンダリングされなくなります。もっと具体的に言うと、コンポーネントがマウントされ、最初のレンダリングがされてからは一切の再レンダリングが行われなくなります。&lt;br&gt;&lt;br&gt;
ある意味では最高のパフォーマンスを得たわけですが、全ての場合においてこれは問題です。  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/reducer-not-pure-anti-pattern-tuenning" rel="noopener noreferrer"&gt;この時点のStackblitzのサンプルです&lt;/a&gt;。  &lt;/p&gt;
&lt;h1&gt;
  
  
  どうするべきなのか
&lt;/h1&gt;

&lt;p&gt;副作用があるような設計が悪いとしか言いようがありません。&lt;br&gt;&lt;br&gt;
ここでは、一番はじめのコードで示した&lt;code&gt;Account&lt;/code&gt;クラスの&lt;code&gt;pushAka(name)&lt;/code&gt;メソッドが悪いです。そこで、次のようなコードに置き換えます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aka&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;pushAka&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPrototypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aka&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aka&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;r&lt;/code&gt;に自分自身を浅いコピーを行い、その上で新しい配列を作っています。とりあえず、これで動きます。&lt;br&gt;&lt;br&gt;
&lt;a href="https://stackblitz.com/edit/reducer-not-pure-anti-pattern-tuenning-successed" rel="noopener noreferrer"&gt;そしてStackblitzのサンプルです&lt;/a&gt;。  &lt;/p&gt;

&lt;p&gt;なお、この場合はこれでうまく動きましたが、さらに複雑なインスタンス、オブジェクト、配列ではこれだけでは解消しないこともあるでしょう。ただし、そのような複雑なデータ構造はそもそも設計が悪い可能性があります。  &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclution
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;&lt;strong&gt;KEEP PURE FUNCTION&lt;/strong&gt;, &lt;strong&gt;SIMPLE DATA STRUCTURE&lt;/strong&gt;&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  余談
&lt;/h2&gt;

&lt;p&gt;これまでのすべてのStackblitzサンプルには&lt;code&gt;redux-logger&lt;/code&gt;が導入されています。特に、副作用が起きている時の&lt;a href="https://stackblitz.com/edit/reducer-not-pure-anti-pattern-tuenning" rel="noopener noreferrer"&gt;1個め&lt;/a&gt;と&lt;a href="https://stackblitz.com/edit/reducer-not-pure-anti-pattern-tuenning" rel="noopener noreferrer"&gt;2個め&lt;/a&gt;で開発ツールを開き、実際にプログラムを動かして、Donald Trumpの二つ名を追加してやりましょう。&lt;br&gt;&lt;br&gt;
何度か試しているうちに、loggerがとても興味深い挙動を記録していることがわかってきます。  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faejtal00hwu41xb26p3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faejtal00hwu41xb26p3g.png" width="748" height="692"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;なんと&lt;code&gt;prev state&lt;/code&gt;と&lt;code&gt;next state&lt;/code&gt;が同一のものになっています。それだけではありません。  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hujmr6nv8cav6msfi39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hujmr6nv8cav6msfi39.png" width="800" height="1120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;過去の出力までもが改変されています――とても興味深く、面白い話ですが、この現象を解説するには私は&lt;code&gt;redux&lt;/code&gt;と&lt;code&gt;redux-logger&lt;/code&gt;の実装に精通していません。誰かこの解説記事を書いてください。私はこれが限界です。&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>japanese</category>
    </item>
    <item>
      <title>HoCとStorybook/addon-infoの落とし穴</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Thu, 19 Jul 2018 15:36:26 +0000</pubDate>
      <link>https://dev.to/origamium/hocstorybookaddon-info-lbc</link>
      <guid>https://dev.to/origamium/hocstorybookaddon-info-lbc</guid>
      <description>&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;Higher-Order Componentsをaddon-infoで表示させようとするとバグる&lt;/p&gt;

&lt;h1&gt;
  
  
  Storybook? Storybook/addon-info?
&lt;/h1&gt;

&lt;p&gt;みなさん、&lt;a href="https://storybook.js.org" rel="noopener noreferrer"&gt;storybook&lt;/a&gt;を使ってますか？コンポーネントを作っていく時に便利すぎるので是非使ってください。説明だるいのでプロジェクトページのexamples見ればすぐわかりの取得ができます。  &lt;/p&gt;

&lt;p&gt;さて、storybookのプラグインである&lt;a href="https://www.npmjs.com/package/@storybook/addon-info" rel="noopener noreferrer"&gt;addon-info&lt;/a&gt;も超便利です。コンポーネントがどのような役割を果たすのか、何を意図して作られたのかをmarkdownで記述すると表示してくれますし、実際にstoryのコード内でどのように使われているかを表示したり、Flowによる型チェックが(たぶんTypeScriptも)定義されていた場合、それも表示してくれます。  &lt;/p&gt;

&lt;p&gt;たとえば、以下のようなコンポーネントがあるとします。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @flow&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* クエスチョンマークの前につく文字列です */&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cm"&gt;/* クエスチョンマークの数 */&lt;/span&gt;
    &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/* めっちゃクエスチョンマークをあれします */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;？&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;は&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;そして、story用のコードは次のようになります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @flow&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;storiesOf&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storybook/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;withInfo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storybook/addon-info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../SuperQuestionLabel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;storiesOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;何もわからん&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;basic usage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;withInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;感動する文章&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;)(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SuperQuestionLabel&lt;/span&gt;
                &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;これからは飲酒の時代&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;)))&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;すると、storybookの当該ページにはInfoボタンが表示され、クリックすると次のようなすばらしいインフォメーション情報が表示されます。  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdp6qbbdux96u3hrupir4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdp6qbbdux96u3hrupir4.png" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;感動する文章、コンポーネントがどのように使われるのかの一例、そしてプロパティの詳細情報、感動ですね。Reactに限らず、今やReactコンポーネントを作るのであればstorybook、そしてaddon-infoは欠かせないものになりつつあります。(残念な点としては、&lt;a href="https://github.com/storybooks/storybook/blob/master/ADDONS_SUPPORT.md" rel="noopener noreferrer"&gt;今の所addon-infoはReactにしか対応してない&lt;/a&gt;点でしょうか)  &lt;/p&gt;

&lt;h1&gt;
  
  
  Main Issue
&lt;/h1&gt;

&lt;p&gt;そんなaddon-infoには天敵が存在します。&lt;strong&gt;Higher-Order Components&lt;/strong&gt;です。  &lt;/p&gt;

&lt;p&gt;その例として、Stateless Functional Componentsで、&lt;a href="https://github.com/acdlite/recompose" rel="noopener noreferrer"&gt;recompose&lt;/a&gt;の機能を使用している場合です。&lt;br&gt;&lt;br&gt;
うまくいかない例を見てみましょう。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @flow&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pure&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;recompose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* クエスチョンマークの前につく文字列です */&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cm"&gt;/* クエスチョンマークの数 */&lt;/span&gt;
    &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/* めっちゃクエスチョンマークをあれします */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;？&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;は&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;pure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;recomposeの&lt;code&gt;pure&lt;/code&gt;を用いてコンポーネントの再レンダリングを抑えています。高いパフォーマンスを求められるWebアプリケーションであれば、&lt;code&gt;pure&lt;/code&gt;や&lt;code&gt;onlyUpdateForKeys&lt;/code&gt;を用いてチューニングを行うことも多々あるでしょう。しかし、StorybookのInfoページは次のようになってしまいます。  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofr6hrlnzqqc528zgpc5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofr6hrlnzqqc528zgpc5.png" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;感動どころか、失望してしまいます。&lt;br&gt;&lt;br&gt;
なぜこのようになるか?理由はこれらの&lt;code&gt;pure&lt;/code&gt;や&lt;code&gt;onlyUpdateForKeys&lt;/code&gt;は&lt;strong&gt;Higher-Order Components&lt;/strong&gt;だからです。するとひとつコンポーネントにコンポーネントがラップされた形になってしまいますから、そのためにaddon-infoが各種情報を拾ってくれなくなるのです。  &lt;/p&gt;
&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;p&gt;HoCしたコンポーネントであることが問題なのですから、素のコンポーネントをstoriesに記述すればいいわけです。&lt;br&gt;&lt;br&gt;
つまり、次のようなコードにします。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @flow&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pure&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;recompose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* クエスチョンマークの前につく文字列です */&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cm"&gt;/* クエスチョンマークの数 */&lt;/span&gt;
    &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/* めっちゃクエスチョンマークをあれします */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;？&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;は&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SuperQuestionLabel_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;pure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SuperQuestionLabel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;export const&lt;/code&gt;を使用して、素のコンポーネントを追加で出力するようにしただけです。&lt;br&gt;&lt;br&gt;
そして、story用のコードも、importするものを変更すればいいのです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @flow&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;storiesOf&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storybook/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;withInfo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storybook/addon-info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ここを変更！&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;SuperQuestionLabel_&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../SuperQuestionLabel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;storiesOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;すべてが理解できた&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;basic usage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;withInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;感動する文章&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;)(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SuperQuestionLabel_&lt;/span&gt;
                &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;これからは飲酒の時代&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;)))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;少々(exportする名前が)雑ではありますが、これでaddon-infoは次のように、期待通りの表示をしてくれます。  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzl4pyevg1bfb6bhzdswx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzl4pyevg1bfb6bhzdswx.png" alt="感動！君も泣け" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Higher-Order Componentsをdefaultで出力しているコンポーネントは、少なくともStorybookのaddon-infoで概要を表示させたいのであれば、素のコンポーネントもexportしてあげよう  &lt;/p&gt;

&lt;h2&gt;
  
  
  END OF FILE
&lt;/h2&gt;

&lt;p&gt;最後の画像のAlt textは「感動！君も泣け」です。&lt;br&gt;&lt;br&gt;
そして私はこの問題におもいっきりハマり、2日無駄にしました。人生は短く、みなさんの人生も短い、だから私は人生の時間をさらに削り、みなさんの人生の時間を無駄にしないよう、記事を書いている…&lt;/p&gt;

</description>
      <category>react</category>
      <category>storybook</category>
      <category>japanese</category>
    </item>
    <item>
      <title>React tutorial code in Stateless Functional Components and Redux</title>
      <dc:creator>Origami</dc:creator>
      <pubDate>Fri, 09 Mar 2018 20:46:48 +0000</pubDate>
      <link>https://dev.to/origamium/react-tutorial-code-in-stateless-functional-components-and-redux--3kp</link>
      <guid>https://dev.to/origamium/react-tutorial-code-in-stateless-functional-components-and-redux--3kp</guid>
      <description>&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;Reduxばっか使ってると脳がへんになるぞ&lt;/p&gt;

&lt;h1&gt;
  
  
  はい
&lt;/h1&gt;

&lt;p&gt;こんにちは。もうおれはつかれた。そしてこれを見てください。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/react-tutorial-sfc-and-redux" rel="noopener noreferrer"&gt;https://stackblitz.com/edit/react-tutorial-sfc-and-redux&lt;/a&gt;&lt;br&gt;
(github repository is &lt;a href="https://github.com/FirstStar/react-tutorial-code-sfc-and-redux" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;埋め込みのやり方わかりません。もう眠いのでどうでもいいです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yp7mm4c876b5zgnbi8t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yp7mm4c876b5zgnbi8t.jpg" alt="tic-tac-toe" width="311" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;内容的にはReactの&lt;a href="https://reactjs.org/tutorial/tutorial.html" rel="noopener noreferrer"&gt;このページ&lt;/a&gt;で書くマルバツゲーム(tic-tac-toe)をStateless Functional Components + Redux(react-redux, redux-actions, reselect, redux-undo@beta)で全部書き直したというだけのことなんですがまあとりあえず見てください。コードがわりと汚い自信はあります。&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Reduxは小規模なプログラムで書いてもただ煩雑なだけ
&lt;/h2&gt;

&lt;p&gt;もう見出しのとおりです。&lt;br&gt;
ただ、学習という意味合いではそれほど無駄ではないかな、とは思いますが。&lt;/p&gt;

&lt;h2&gt;
  
  
  そもそもReduxを使う意味
&lt;/h2&gt;

&lt;p&gt;これは若干ポエム要素を含みます（完全に個人の見解です）が、Reduxはプロジェクトの構造を少し複雑にする分、それぞれのアクションの責任を小さく分割するような制約を要求してくるため、ある程度の規模を持ち、かつ複数人が関わるようなプロジェクトでその効果を存分に発揮してくれるものと認識しています。&lt;/p&gt;

&lt;p&gt;「規模」というのが肝要で、どれほど大きくなればReduxが威力を発揮するのか？&lt;br&gt;
それはグラデーション的な曖昧な境界線を挟む問題なので、ここで説明はしませんが、このぐらい小規模だとReduxはむしろコードの分量をいたずらに増やし、煩雑にしてしまうだけである以上、やはり「Reduxを使わない」という選択肢は十分に有り得る、という、当たり前のような無意味な解答をみなさんに提供します。&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>tutorial</category>
      <category>japanese</category>
    </item>
  </channel>
</rss>
