React では通常、親コンポーネントから子コンポーネントの値を引き渡すには props を通じて引き渡します。
子コンポーネントは渡されたその props を constructor で state などに保存して利用します。
実はこの値の受け渡しは「親→子」でしか利用できず「子→親」の値の受け渡しは props を通じては行えません。
(子コンポーネントでは親から渡された props はリードオンリーです。)
でもどうしても子コンポーネントから親コンポーネントの値(State)を変更したい場合があります。
そんな時はどうすればよいのかをこの記事では解説します。
React 環境の作成方法は以下のサイトを参照して作成してください。

Reactで親から子の値(State)を変更する
React ではコンポーネント間の値の受け渡しは props を用いて「親コンポーネント→子コンポーネント」へ渡します。
まずは、親コンポーネントのソースです。
import React from "react" ;
import Child from "./Child" ;
export default class Parent extends React.Component {
constructor( props ){
super( props ) ;
this.state ={ count : 0 } ;
this.countUp = this.countUp.bind(this);
}
countUp( flg ){
if( flg == "up" ){
this.setState( { count : this.state.count + 1 } ) ;
}
else{
this.setState( { count : this.state.count - 1 } ) ;
}
}
render(){
return(
<React.Fragment>
<input type="button" value="カウントアップ" onClick={( event ) => { this.countUp( 'up' ) ; }} />
<input type="button" value="カウントダウン" onClick={( event ) => { this.countUp( 'down' ) ; }} />
<Child
count={this.state.count}
/>
</React.Fragment>
) ;
}
}
次に子コンポーネントのソースです。
import React from "react" ;
export default class Child extends React.Component {
constructor( props ){
super( props ) ;
this.state = { count : this.props.count, } ;
}
render(){
return(
<React.Fragment>
<div>count={this.state.count}</div>
</React.Fragment>
);
}
componentDidUpdate( prevProps ){
if( prevProps.count != this.props.count ){
this.setState({ count : this.props.count } );
}
}
}
これで親コンポーネントのボタンをクリックすると連動して子コンポーネントで count の値を動的に変更することができます。
Reactで子から親の値(State)を変更する
React で子コンポーネントから親コンポーネントの値(State)を変更するには親コンポーネントを変更するコールバック関数作成し、その関数を子コンポーネントへ props を通じして渡して、子コンポーネント側でコールバック関数を適宜呼び出します。
まずは、親コンポーネントのソースです。
import React from "react" ;
import Child from "./Child" ;
export default class Parent extends React.Component {
constructor( props ){
super( props ) ;
this.state = { count : 0 } ;
this.countUp = this.countUp.bind(this);
}
//stateのcountの値を更新するコールバック関数
countUp( flg ){
this.setState( { count : this.state.count + flg } ) ;
}
render(){
return(
<React.Fragment>
<div>count={this.state.count}</div>
<Child
callback={this.countUp}
/>
</React.Fragment>
) ;
}
}
上記のソースで countUp メソッドが子コンポーネント関数に引き渡すコールバック関数です。
次にコールバック関数を受け取る側の子コンポーネントのソースです。
import React from "react" ;
export default class Child extends React.Component {
constructor( props ){
super( props ) ;
this.state = { callback : this.props.callback, } ;
this.CallBackFunction = this.CallBackFunction.bind(this);
}
CallBackFunction( flg ){
if( flg == "up" ){
this.state.callback( 1 ) ;
}
else{
this.state.callback( -1 ) ;
}
}
render(){
return(
<React.Fragment>
<input type="button" value="カウントアップ" onClick={( event ) => { this.CallBackFunction( 'up' ) ; }} />
<input type="button" value="カウントダウン" onClick={( event ) => { this.CallBackFunction( 'down' ) ; }} />
</React.Fragment>
);
}
}
子コンポーネント側で用意したカウントアップ、カウントダウンボタンのクリックイベントで親コンポーネントから渡されたコールバック関数を呼び出します。
こうすることで結果的に子コンポーネントから親コンポーネントの値(State)を変更することができるようになります。
まとめ
React で子コンポーネントから親コンポーネントの値(State)を変更するには親コンポーネントを変更するコールバック関数作成し、その関数を子コンポーネントへ props を通じして渡すことで、子コンポーネントから親コンポーネントの値(State)を変更することができます。
