{"componentChunkName":"component---src-modules-datocms-post-page-page-tsx","path":"/posts/29","result":{"data":{"post":{"title":"React Componentでthisがundefinedになる問題の解決策","author":{"name":"suin","images":{"r32":{"src":"https://www.datocms-assets.com/29850/1591833290-avatar512.jpg?auto=format&fm=png&h=32&mask=ellipse&w=32","srcSet":"https://www.datocms-assets.com/29850/1591833290-avatar512.jpg?auto=format&dpr=1&fm=png&h=32&mask=ellipse&w=32 1x,\nhttps://www.datocms-assets.com/29850/1591833290-avatar512.jpg?auto=format&dpr=1.5&fm=png&h=32&mask=ellipse&w=32 1.5x,\nhttps://www.datocms-assets.com/29850/1591833290-avatar512.jpg?auto=format&dpr=2&fm=png&h=32&mask=ellipse&w=32 2x,\nhttps://www.datocms-assets.com/29850/1591833290-avatar512.jpg?auto=format&dpr=3&fm=png&h=32&mask=ellipse&w=32 3x"},"r48":{"src":"https://www.datocms-assets.com/29850/1591833290-avatar512.jpg?auto=format&fm=png&h=48&mask=ellipse&w=48","srcSet":"https://www.datocms-assets.com/29850/1591833290-avatar512.jpg?auto=format&dpr=1&fm=png&h=48&mask=ellipse&w=48 1x,\nhttps://www.datocms-assets.com/29850/1591833290-avatar512.jpg?auto=format&dpr=1.5&fm=png&h=48&mask=ellipse&w=48 1.5x,\nhttps://www.datocms-assets.com/29850/1591833290-avatar512.jpg?auto=format&dpr=2&fm=png&h=48&mask=ellipse&w=48 2x,\nhttps://www.datocms-assets.com/29850/1591833290-avatar512.jpg?auto=format&dpr=3&fm=png&h=48&mask=ellipse&w=48 3x"}},"bio":"好き: TypeScript, DDD, OOP／#YYTypeScript の主催者／Qiita 4位／株式会社クラフトマンソフトウェア取締役／『実践ドメイン駆動設計』邦訳レビュア／#分報 考案者／Web自動テストShouldBeeを開発"},"date":"2015年7月5日","tags":["Inside-ShouldBee","React","ES6"],"category":"プログラミング","body":"<a href=\"https://c16e-esa-io-public-files.s3-ap-northeast-1.amazonaws.com/uploads/production/attachments/15637/2020/05/28/18740/0e2a7371-b8bb-4034-9876-23341c9cae45.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img width=\"1200\" alt=\"image.png (34.7 kB)\" src=\"https://c16e-esa-io-public-files.s3-ap-northeast-1.amazonaws.com/uploads/production/attachments/15637/2020/05/28/18740/0e2a7371-b8bb-4034-9876-23341c9cae45.png\"></a>\n<p data-sourcepos=\"3:1-3:64\">最近、ShouldBeeのUIをReact.jsで作り始めています。</p>\n<p data-sourcepos=\"5:1-5:182\">Babelを使ってES6のclass構文でReactのComponentを作っているのですが、どうもコールバックのメソッドで<code>this</code>が<code>undefined</code>になってしまいます。</p>\n<p data-sourcepos=\"7:1-7:232\">例えば、下のJSはボタンのコンポーネントで、クリックしたときに、<code>onClick</code>メソッドが呼ばれます。<code>onClick</code>メソッドの中で、<code>this</code>を参照していますが、<code>undefined</code>になります。</p>\n<div class=\"code-block\" data-sourcepos=\"9:1-23:3\">\n<div class=\"code-filename\">\n<i class=\"fa fa-file-code-o\"></i>jsx</div>\n<div class=\"highlight\"><pre class=\"highlight jsx\"><code><span class=\"k\">import</span> <span class=\"nx\">React</span> <span class=\"k\">from</span> <span class=\"dl\">\"</span><span class=\"s2\">react</span><span class=\"dl\">\"</span><span class=\"p\">;</span>\n\n<span class=\"k\">export</span> <span class=\"k\">default</span> <span class=\"kd\">class</span> <span class=\"nx\">Button</span> <span class=\"kd\">extends</span> <span class=\"nx\">React</span><span class=\"p\">.</span><span class=\"nx\">Component</span> <span class=\"p\">{</span>\n  <span class=\"nx\">onClick</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"k\">this</span><span class=\"p\">);</span> <span class=\"c1\">// undefined</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"nx\">render</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"p\">(</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">onClick</span><span class=\"p\">=</span><span class=\"si\">{</span><span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">onClick</span><span class=\"si\">}</span><span class=\"p\">&gt;</span>Button<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n</div>\n<p data-sourcepos=\"25:1-25:118\">ここでは、この問題を解決する方法を紹介したいと思います。解決方法は4つあります。</p>\n<h1 data-sourcepos=\"27:1-27:30\" id=\"1-0-0\" name=\"1-0-0\">\n<a class=\"anchor\" id=\"解決策1: XMLの中でbind\" name=\"%E8%A7%A3%E6%B1%BA%E7%AD%961:%20XML%E3%81%AE%E4%B8%AD%E3%81%A7bind\" href=\"#%E8%A7%A3%E6%B1%BA%E7%AD%961:%20XML%E3%81%AE%E4%B8%AD%E3%81%A7bind\" data-position=\"1-0-0\"><i class=\"fa fa-link\"></i><span class=\"hidden\" data-text=\"解決策1__colon__ XMLの中でbind\"> &gt; 解決策1__colon__ XMLの中でbind</span></a>解決策1: XMLの中でbind</h1>\n<p data-sourcepos=\"29:1-29:58\">１つ目はXMLの中で<code>this</code>をbindする方法です。</p>\n<div class=\"code-block\" data-sourcepos=\"31:1-37:3\">\n<div class=\"code-filename\">\n<i class=\"fa fa-file-code-o\"></i>jsx</div>\n<div class=\"highlight\"><pre class=\"highlight jsx\"><code>  <span class=\"nx\">render</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"p\">(</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">onClick</span><span class=\"p\">=</span><span class=\"si\">{</span><span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">onClick</span><span class=\"p\">.</span><span class=\"nx\">bind</span><span class=\"p\">(</span><span class=\"k\">this</span><span class=\"p\">)</span><span class=\"si\">}</span><span class=\"p\">&gt;</span>Button<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n</code></pre></div>\n</div>\n<h1 data-sourcepos=\"39:1-39:34\" id=\"2-0-0\" name=\"2-0-0\">\n<a class=\"anchor\" id=\"解決策2: Autobindingを使う\" name=\"%E8%A7%A3%E6%B1%BA%E7%AD%962:%20Autobinding%E3%82%92%E4%BD%BF%E3%81%86\" href=\"#%E8%A7%A3%E6%B1%BA%E7%AD%962:%20Autobinding%E3%82%92%E4%BD%BF%E3%81%86\" data-position=\"2-0-0\"><i class=\"fa fa-link\"></i><span class=\"hidden\" data-text=\"解決策2__colon__ Autobindingを使う\"> &gt; 解決策2__colon__ Autobindingを使う</span></a>解決策2: Autobindingを使う</h1>\n<p data-sourcepos=\"41:1-41:223\"><a href=\"https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding\" target=\"_blank\" rel=\"noopener noreferrer\">React v0.13.0 Beta 1 | React</a>で紹介されている方法です。コンストラクタでバインドするというものです。</p>\n<div class=\"code-block\" data-sourcepos=\"44:1-61:3\">\n<div class=\"code-filename\">\n<i class=\"fa fa-file-code-o\"></i>jsx</div>\n<div class=\"highlight\"><pre class=\"highlight jsx\"><code><span class=\"k\">export</span> <span class=\"k\">default</span> <span class=\"kd\">class</span> <span class=\"nx\">Button</span> <span class=\"kd\">extends</span> <span class=\"nx\">React</span><span class=\"p\">.</span><span class=\"nx\">Component</span> <span class=\"p\">{</span>\n  <span class=\"kd\">constructor</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"k\">super</span><span class=\"p\">();</span>\n    <span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">onClick</span> <span class=\"o\">=</span> <span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">onClick</span><span class=\"p\">.</span><span class=\"nx\">bind</span><span class=\"p\">(</span><span class=\"k\">this</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"nx\">onClick</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"k\">this</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"nx\">render</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"p\">(</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">onClick</span><span class=\"p\">=</span><span class=\"si\">{</span><span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">onClick</span><span class=\"si\">}</span><span class=\"p\">&gt;</span>Button<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n</div>\n<h1 data-sourcepos=\"63:1-63:52\" id=\"3-0-0\" name=\"3-0-0\">\n<a class=\"anchor\" id=\"解決策3: @autobindデコレーターを使う\" name=\"%E8%A7%A3%E6%B1%BA%E7%AD%963:%20@autobind%E3%83%87%E3%82%B3%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%92%E4%BD%BF%E3%81%86\" href=\"#%E8%A7%A3%E6%B1%BA%E7%AD%963:%20@autobind%E3%83%87%E3%82%B3%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%92%E4%BD%BF%E3%81%86\" data-position=\"3-0-0\"><i class=\"fa fa-link\"></i><span class=\"hidden\" data-text=\"解決策3__colon__ __at__autobindデコレーターを使う\"> &gt; 解決策3__colon__ __at__autobindデコレーターを使う</span></a>解決策3: <code>@autobind</code>デコレーターを使う</h1>\n<p data-sourcepos=\"65:1-65:401\">ES7で提案されている機能の<a href=\"https://github.com/wycats/javascript-decorators\" target=\"_blank\" rel=\"noopener noreferrer\">デコレーター</a>を使う方法です。<a href=\"https://github.com/andreypopp/autobind-decorator\" target=\"_blank\" rel=\"noopener noreferrer\">andreypopp/autobind-decorator</a>というライブラリが公開されていて、これをnpmでインストールしておくとメソッドに対して、<code>@autobind</code>デコレーターを使えるようになります。</p>\n<div class=\"code-block\" data-sourcepos=\"67:1-80:3\">\n<div class=\"code-filename\">\n<i class=\"fa fa-file-code-o\"></i>jsx</div>\n<div class=\"highlight\"><pre class=\"highlight jsx\"><code><span class=\"k\">export</span> <span class=\"k\">default</span> <span class=\"kd\">class</span> <span class=\"nx\">Button</span> <span class=\"kd\">extends</span> <span class=\"nx\">React</span><span class=\"p\">.</span><span class=\"nx\">Component</span> <span class=\"p\">{</span>\n  <span class=\"p\">@</span><span class=\"nd\">autobind</span>\n  <span class=\"nx\">onClick</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"k\">this</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"nx\">render</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"p\">(</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">onClick</span><span class=\"p\">=</span><span class=\"si\">{</span><span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">onClick</span><span class=\"si\">}</span><span class=\"p\">&gt;</span>Button<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n</div>\n<h1 data-sourcepos=\"82:1-82:43\" id=\"4-0-0\" name=\"4-0-0\">\n<a class=\"anchor\" id=\"解決策4: Function Bind Syntaxを使う\" name=\"%E8%A7%A3%E6%B1%BA%E7%AD%964:%20Function%20Bind%20Syntax%E3%82%92%E4%BD%BF%E3%81%86\" href=\"#%E8%A7%A3%E6%B1%BA%E7%AD%964:%20Function%20Bind%20Syntax%E3%82%92%E4%BD%BF%E3%81%86\" data-position=\"4-0-0\"><i class=\"fa fa-link\"></i><span class=\"hidden\" data-text=\"解決策4__colon__ Function Bind Syntaxを使う\"> &gt; 解決策4__colon__ Function Bind Syntaxを使う</span></a>解決策4: Function Bind Syntaxを使う</h1>\n<p data-sourcepos=\"84:1-84:397\"><a href=\"https://github.com/zenparsing/es-function-bind\" target=\"_blank\" rel=\"noopener noreferrer\">Function Bind Syntax</a>もまたES7で提案されている機能のひとつで、メソッドの頭に<code>::</code>をつけると<code>this</code>がbindできるというものです。<code>::foo</code>は<code>foo.bind(this)</code>のシュガーシンタクスになります。React Componentの場合はXMLの中で<code>onClick={::this.onClick}</code>のように使うことができます。</p>\n<div class=\"code-block\" data-sourcepos=\"86:1-98:3\">\n<div class=\"code-filename\">\n<i class=\"fa fa-file-code-o\"></i>jsx</div>\n<div class=\"highlight\"><pre class=\"highlight jsx\"><code><span class=\"k\">export</span> <span class=\"k\">default</span> <span class=\"kd\">class</span> <span class=\"nx\">Button</span> <span class=\"kd\">extends</span> <span class=\"nx\">React</span><span class=\"p\">.</span><span class=\"nx\">Component</span> <span class=\"p\">{</span>\n  <span class=\"nx\">onClick</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"k\">this</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"nx\">render</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"p\">(</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">onClick</span><span class=\"p\">=</span><span class=\"si\">{</span><span class=\"p\">::</span><span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">onClick</span><span class=\"si\">}</span><span class=\"p\">&gt;</span>Button<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n</div>\n<p data-sourcepos=\"100:1-100:210\">以上が解決策の紹介になります。なお、解決策3,4については、記事執筆時点でES7の提案中の構文になるので、変更または却下されている可能性があります。</p>\n"}},"pageContext":{"id":"DatoCmsPost-5142964-ja","description":"最近、ShouldBeeのUIをReact.jsで作り始めています。 Babelを使ってES6のclass構文でReactのComponentを作っているのですが、どうもコールバックのメソッドでthisがundefinedになってしまいます。 例えば、下のJSはボタンのコンポーネントで、クリックしたときに、onClickメソッドが呼ばれます。onClickメソッドの中で、thisを参照していますが、undefinedになります。 ここでは、この問題を解決する方法を紹介したいと思います。解決方法は4つあります。 解決策1: XMLの中でbind １つ目はXMLの中でthisをbindする方法です","toc":[{"tag":"h1","depth":1,"href":"#%E8%A7%A3%E6%B1%BA%E7%AD%961:%20XML%E3%81%AE%E4%B8%AD%E3%81%A7bind","text":"解決策1: XMLの中でbind","html":"解決策1: XMLの中でbind"},{"tag":"h1","depth":1,"href":"#%E8%A7%A3%E6%B1%BA%E7%AD%962:%20Autobinding%E3%82%92%E4%BD%BF%E3%81%86","text":"解決策2: Autobindingを使う","html":"解決策2: Autobindingを使う"},{"tag":"h1","depth":1,"href":"#%E8%A7%A3%E6%B1%BA%E7%AD%963:%20@autobind%E3%83%87%E3%82%B3%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%92%E4%BD%BF%E3%81%86","text":"解決策3: @autobindデコレーターを使う","html":"解決策3: <code>@autobind</code>デコレーターを使う"},{"tag":"h1","depth":1,"href":"#%E8%A7%A3%E6%B1%BA%E7%AD%964:%20Function%20Bind%20Syntax%E3%82%92%E4%BD%BF%E3%81%86","text":"解決策4: Function Bind Syntaxを使う","html":"解決策4: Function Bind Syntaxを使う"}],"ogpImageUrl":"https://www.datocms-assets.com/29850/1593190022-pastedimage20200627146.png?fm=png&mark64=aHR0cHM6Ly93d3cuZGF0b2Ntcy1hc3NldHMuY29tLzI5ODUwLzE1OTMxNTQ2MzYtdHJhbnNwYXJlbnQtcGl4ZWwucG5nP3c9NDAwJmg9NjQmZml0PWNyb3AmYmxlbmQ2ND1hSFIwY0hNNkx5OTNkM2N1WkdGMGIyTnRjeTFoYzNObGRITXVZMjl0THpJNU9EVXdMekUxT1RFNE16TXlPVEF0WVhaaGRHRnlOVEV5TG1wd1p6OXRZWE5yUFdWc2JHbHdjMlVtWm0wOWNHNW5KbmM5TWpVMkptZzlNalUyJmJsZW5kLWg9NjQmYmxlbmQteD0wJmJsZW5kLXk9MCZibGVuZC1tb2RlPW5vcm1hbCZtYXJrNjQ9YUhSMGNITTZMeTloYzNObGRITXVhVzFuYVhndWJtVjBMMzUwWlhoMFAzUjRkQzFoYkdsbmJqMXRhV1JrYkdVbE1rTnNaV1owSm5SNGRDMW1iMjUwUFhOaGJuTXRjMlZ5YVdZbE1rTmliMnhrSm5SNGRDMWpiMnh2Y2oweU1qRTRNVFltZEhoME5qUTlZek5XY0dKbkpuUjRkQzF6YVhwbFBUTXdKbWc5TmpRJm1hcmsteD02NCZtYXJrLWFsaWduPW1pZGRsZSUyQ2xlZnQ&mark-align=bottom%2Cleft&mark-x=100&mark-y=496&blend64=aHR0cHM6Ly93d3cuZGF0b2Ntcy1hc3NldHMuY29tLzI5ODUwLzE1OTMxNTQ2MzYtdHJhbnNwYXJlbnQtcGl4ZWwucG5nP3c9MTIwMCZoPTYzMCZmaXQ9Y3JvcCZtYXJrNjQ9YUhSMGNITTZMeTkzZDNjdVpHRjBiMk50Y3kxaGMzTmxkSE11WTI5dEx6STVPRFV3THpFMU9UTXhOVEE1TkRBdFkzSmhablJ6YldGdUxUQXhMbkJ1WncmbWFyay1hbGlnbj10b3AlMkNjZW50ZXImbWFyay13PTI1MCZtYXJrLXk9ODAmYmxlbmQ2ND1hSFIwY0hNNkx5OWhjM05sZEhNdWFXMW5hWGd1Ym1WMEwzNTBaWGgwUDNSNGRDMWhiR2xuYmoxdGFXUmtiR1VsTWtOalpXNTBaWEltZEhoMExXWnZiblE5YzJGdWN5MXpaWEpwWmlVeVEySnZiR1FtZEhoMExYQmhaRDB4TURBbWRIaDBMV052Ykc5eVBUSXlNVGd4TmlaMGVIUTJORDFWYlZab1dUTlJaMUV5T1hSalJ6bDFXbGMxTURRMFIyNWtSMmh3WXkxUFFtcElWblZhUjFadFlWYzFiRnBQVDBKeExVOUNjWFZQUTJrdFYxWnFMVzFvYWs5UFFuSjFhVzV2TFdGNGRYVmxkR3huSm5SNGRDMXphWHBsUFRVMUpuYzlNVEl3TUNab1BUWXpNQSZibGVuZC1tb2RlPW5vcm1hbA&blend-mode=normal","otherPost":{"type":"author","title":"ブログの起承転結は読み手にとって非効率なので、結論ファーストで書いたほうがいいと思う","slug":"/posts/37"}}}}