質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

2282閲覧

親コンポーネントのstateを変更したい(react)

k10a

総合スコア35

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2018/12/20 08:43

編集2018/12/20 08:47

閲覧いただき、ありがとうございます。

子コンポーネントで setState() して、親コンポーネントのstateを変更したいのですが、できるものとできないものがあり、困っています。
具体的には、下記ソースコードの items は変更できているのですが、 mainIndex は変更できていません。

JavaScript

1// App.js 2 3import PrimaryItem from "./components/PrimaryItem"; 4 5class App extends Component { 6 constructor(props) { 7 super(props); 8 this.state = { 9 items: { 10 0: { 11 id: 1, 12 color: "red" 13 }, 14 1: { 15 id: 2, 16 color: "blue" 17 } 18 }, 19 // mainIndexを変更したい 20 mainIndex: 0 21 } 22 } 23 24 render() { 25 return( 26 <PrimaryItem items={this.state.items} mainIndex={this.state.mainIndex} 27 ); 28 } 29}

JavaScript

1// PrimaryItem.js 2 3class PrimaryItem extends Component { 4 5 _clickColor = id => () => { 6 const items = [...this.props.items]; 7 const item = items.find(item => item.id === id); 8 item.color = "black" 9 this.setState({ 10 item 11 mainItemIndex: item.number 12 }); 13 }; 14・・・ 15}

mainIndexをsetStateする前に変更しようと思い、下記のようにやってみたのですが

JavaScript

1 _clickColor = id => () => { 2 const items = [...this.props.items]; 3 const item = items.find(item => item.id === id); 4 const mainIndex = this.props.mainIndex 5 item.color = "black" 6 mainIndex = item.number 7 this.setState({ 8 item 9 mainItemIndex 10 }); 11 };

エラーが出てしまいました。

Syntax error: "mainIndex" is read-only

すみませんが、どなたかお知恵を拝借させていただければと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

下記手順で修正すると良いかと思いましたので回答させていただきます。

  • PrimaryItemにある_clickColor()を親のcomponentとなるAppに持っていく
  • そのfunctionをpropsとしてPrimaryItemに渡す
  • もともとPrimaryItem_clickColor()を呼んでいた箇所でpropsで渡したfunctionを呼ぶように変更

参考:
https://qiita.com/w-tdon/items/7b0f72a3b0a3e0708741

投稿2018/12/20 10:02

編集2018/12/20 10:04
takepo0928

総合スコア21

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k10a

2018/12/21 11:11

ありがとうございます。 親コンポーネントに持っておかなければならないのですね。 参考にさせていただきます!
guest

0

ベストアンサー

こんにちは。

まず、

エラーが出てしまいました。

Syntax error: "mainIndex" is read-only

とのことですが、上記エラーの原因は、以下

javascript

1const mainIndex = this.props.mainIndex

にて const で定義した変数 mainIndex に、その2行下で

javascript

1mainIndex = item.number

と、代入しようとしているからです。

次に、本題の「親コンポーネントのstateを変更したい」についてですが、親のほうで this.state を更新するメソッドを作って、それを子コンポーネントに props で渡し、子のほうで、それを使えばよいです。

具体例として、以下のようなサンプルを以下に作成しました。

  • 親コンポーネント Appthis.state.mainIndex を、子コンポーネント MainIndexBox で表示、変更します。

 

  • this.state.mainIndexを変えるというテーマにフォーカスするために、Appthis.state.items を持っていません。

 

  • MainIndexBox は、Appthis.state.mainIndex を表示、変更するだけなので、MainIndexBox自体は state を持つ必要がないため、Functional Component にしています。

以下は上記の仕様を実装したコードの一例です。(他にも書き方はあるでしょう。)

App

JSX

1class App extends React.Component { 2 constructor(props) { 3 super(props); 4 this.state = { 5 mainIndex: 0, 6 }; 7 this.onMainIndexChange = this.onMainIndexChange.bind(this); 8 } 9 10 onMainIndexChange(mainIndex) { 11 this.setState({ mainIndex }); 12 } 13 14 render() { 15 return ( 16 <MainIndexBox 17 value={this.state.mainIndex} 18 onChange={e => this.onMainIndexChange(e.target.value)} 19 /> 20 ); 21 } 22}

MainIndexBox

JSX

1const MainIndexBox = ({ value, onChange }) => ( 2 <div class="box"> 3 <input type="number" onChange={onChange} defaultValue={value} /> 4 <span class="view">mainIndex: {value}</span> 5 </div> 6);

以下は、上記のコンポーネントを動かせるようにしたサンプルです。

これは、以下
イメージ説明
のように表示され、左側の <input /> で数字を変えれば、右側の表示に反映されることが確認できると思います。

以上、参考になれば幸いです。

投稿2018/12/20 11:15

編集2018/12/20 23:16
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k10a

2018/12/21 11:12

ご丁寧な回答をいただきまして、ありがとうございます。 非常に参考になります。こちらで実行するようにいたします。
jun68ykt

2018/12/21 13:42

どうもです。 state の変更は、なるべく上のほう(親側)に寄せて、できれば子コンポーネントは全て、 state を持たない Functional Component に出来ないか?というところから考えていくのがよいかと思います。
k10a

2018/12/22 01:31

なるほど。書いていた時は、子コンポーネントに関わるものは子コンポーネントに寄せたいと考えていましたが、あまり良くない思想だったんですね。親コンポーネントがだらだらなるの良くないと思っていまして、、ただ今後はそういう書き方を心がけるようにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問