【JavaScript】Reactで子コンポーネントに引数がある関数を渡す方法
Reactでは子コンポーネントに対し、propsの値として関数を渡すことがよくあります。
子コンポーネントから親コンポーネントのStateの値を更新する処理を作るなど、何かと使い道は多いですが、引数付きの関数を渡す際、少しトラブルが起きてしまう方も多いでしょう。
そこで今回は、表題のように引数がある関数を渡す方法について簡潔に解説していきます。
※当記事はReact Hooksなどの関数型の記法ではなく、クラスを用いたレガシーな記法で解説します。あらかじめご了承ください。
サンプルコード
ここでは計算をする親コンポーネントとレンダリングを担う子コンポーネントを作りましょう。
表題の処理を再現するため、特に意味はないですが計算用の数値は子側で管理することにします。
// 親コンポーネント
class Calcer extends React.Component {
constructor(props){
super(props);
this.number = 0;
}
// 計算用の処理
addNum(adder){
// 引数で渡された数値adderを加算し更新
this.number += adder;
return this.number;
}
// 描画
render(){
return(
<div>
<ResultViewer
calc = // ここで関数を渡したい
/>
</div>
)
}
}
// 子コンポーネント
class ResultViewer extends React.Component {
constructor(props){
super(props);
this.state = {
number: 0
}
// 加算する値
this.adder = 1;
}
componentDidMount() {
setInterval(() => {
this.setState({
// 親コンポーネントの関数の戻り値(計算結果)をstateに代入
number: this.props.calc(this.adder)
});
}, 1000);
setInterval(() => {
// 3秒ごとに加算する値を5増やす
this.adder += 5;
}, 3000);
}
render(){
return(
<h1>{this.state.number}</h1>
)
}
}
// 実際に描画を開始
let target = document.getElementById("target");
ReactDOM.render(
<Calcer />,
target
);
上のコードは、以下のように関数を子コンポーネントに渡す処理だけを省いているものなので、まだ動きません。
calc = // ここで関数を渡したい
正直、実務では怒られるレベルのクソコードですが、今回は引数の取り扱いについて解説したいので、敢えて面倒な処理にしています。
引数付きの関数の渡し方
Reactで子コンポーネントに引数付きの関数を渡す場合、以下のようにシンプルに書けばOKです。
<ResultViewer
// calcという値に親コンポーネントの持つ関数を代入
calc = { this.addNum(adder) }
/>
サンプルコードでは、以下のようにここで渡した関数を呼び出しています。
this.setState({
// コレ
number: this.props.calc(this.adder)
});
この方法で渡す場合、実行されるのは親コンポーネント側の関数なので、子コンポーネントから親コンポーネントのデータを操作可能になるわけです。
上記コードで不完全だった部分を書き換えると、以下のように子コンポーネントで更新された数字が描画できているはず。

ここで解説するより、公式リファレンスでとても詳しく解説されているので、詳細はそちらで学んでみてください。
エラーが発生する場合
基本は前述した書き方で動くのですが、関数をコンポーネントとして扱うことがあるなど、Reactは関数の取り扱いが独特で、環境やタイミングによってはあの記述だとエラーが発生することがあります。
より確実に関数を渡したい場合は、以下のように書くのがおすすめです。
calc = {(adder)=>{return this.addNum(adder)}}
行っている処理について解説するのですが、まず以下のように無名関数と呼ばれる形で、propsに関数を渡しています。
() => {
// 実行したい処理
}
関数というよりは、calcという値が呼び出された場合に実行される処理を書いていると言うのが正しいでしょう。
要するに、呼び出し時に実行される処理の中で改めて本来渡したかった関数を呼び出すという回りくどい処理になっています。
可能であれば回りくどい処理は避けたいところですが、この方法であれば確実にエラーが発生せずに上手く動いてくれます。
まとめ
今回は少し特殊なケースについて解説したので、内容が多少わかりにくかったかもしれません。
「Reactで引数付きの関数を上手く渡せない!」という方は、この記事の内容を参考にしてみてください。