背景
ReactやReduxの記事やドキュメントを呼んでいると、度々「副作用」という単語を目にします。医薬品における副作用しか連想できなかったので、ちゃんと調べてみました。
プログラミングにおける副作用とは
副作用は「プログラミング」という大きな枠で用いる単語であり、ここでは触れませんが、主に関数型プログラミングや並行処理の議論で活躍する概念です。
何がプログラミングにおける副作用なのか、明確な定義はありません(言語ごとの定義はあるのかもしれませんが)。しかし、以下2つの関数による処理のことを「副作用」と呼ぶことが多いです。。
1. 引数以外の要因で結果が変わってしまう関数
2. 関数の外に影響を与えてしまう関数
「引数以外の要因で結果が変わってしまう関数」についてですが、例えば、関数f(1)と関数f(2)のように引数が違う場合に別の結果が返ってくるのは全く問題ありません。しかし、グローバル変数などで関数f(x)の結果が変わってしまうと、再利用性がなくなったり、テストができなくなったりといった問題が発生してしまいます。
「関数の外に影響を与えてしまう関数」についてですが、グローバル変数を変更したり、与えられた配列に要素を加えてしまったりといった処理が関数の中にあれば、関数の外に影響を与えてしまっていることになります。これも「引数以外の要因で結果が変わってしまう関数」と同じ問題が発生することになります。
ここまでで、プログラミングにおける「副作用」とは、医薬品における「副作用」と同じようなニュアンスで使われていることがわかりました。また、上記に挙げたような問題を避けるため、一般的に「副作用」は、プログラミングにおいてもネガティブな用語であると言えます。
Reactにおける副作用
Reactにおいては「副作用=書くべきではない」ではなく、「副作用=適切な場所に配置するべき」という扱いです。ネガティブワードとして扱っていないのが混乱する原因だと思います。
Reactにおいて具体的にはどのような処理が副作用であるかというと
- DOMの変更
- APIとの通信
- console.log
- ファイルへの書き込み
- state/propsの変更
- オブジェクトまたはその内部のプロパティへの代入
- 配列のpush()
などです。これらは全て、上述の「関数の外に影響を与えてしまう関数」に当てはまります。
「ネガティブな部分はさておき、副作用は便利だから使います。でも配置に注意してください」という感じです。
まとめ
- プログラミングにおける副作用は医薬品における副作用と同じニュアンスで解釈できる
- Reactにおける副作用は、便利なので適切に扱いましょう