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

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

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

URL(ユニフォームリソースロケータ)とは、インターネット上のリソース(Webページや電子メールの宛先等)を特定するための形式的な記号の並びの事を言う。

パス

パス(path)はファイルシステムの場所(階層)を明示したものです。

JavaScript

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

React.js

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

Q&A

解決済

1回答

1199閲覧

[React]リンクをクリックしてもコンポーネントが入れ替わらない

youj_biginner

総合スコア7

URL

URL(ユニフォームリソースロケータ)とは、インターネット上のリソース(Webページや電子メールの宛先等)を特定するための形式的な記号の並びの事を言う。

パス

パス(path)はファイルシステムの場所(階層)を明示したものです。

JavaScript

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

React.js

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

0グッド

0クリップ

投稿2020/04/08 09:00

編集2020/04/08 13:15

* 分かりにくかったので大幅に編集しています。患っている問題は変わっておりません。

#リンクをクリックしてもコンポーネントが入れ替わらない
リンクを押すとlocalhost:3000/pythonのように押した言語のページに行き、URLパスを取得し、python完全に理解したと表示されるようになっています。しかし、そのページから他の言語のリンクを押しても、下の画像のようにコンポーネントは入れ替わらないままです。(ページをリロードするとようやく入れ替わります。)

pythonと押した時
イメージ説明

JavaScriptと押した時
イメージ説明

該当のコード

App.js

javascript

1import React, { Component } from 'react'; 2import {Switch, Route, Link} from 'react-router-dom'; 3import './App.css'; 4 5import Card from './components/Card/Card' 6 7class App extends Component { 8 state = { 9 query: '' 10 } 11 12 setLang(lang) { 13 this.setState({query: lang}) 14 } 15 16 render () { 17 const langs = ["python", "javascript", "go", "React", "Swift"]; 18 19 return( 20 <div> 21 <header> 22 <h2>Connpassion</h2> 23 <ul>{ langs.map((lang, idx) => { 24 return <li key={idx} onClick={this.setLang.bind(this, lang)}> 25 <Link to={'/' + lang}>{lang}</Link></li> 26 }) } 27 </ul> 28 </header> 29 <div> 30 <Switch> 31 <Route exact path="/">表示したい言語を選んでください</Route> 32 <Route path={'/' + this.state.query} component={Card} /> 33 </Switch> 34 </div> 35 </div> 36 ); 37 } 38} 39 40export default App;

Card.js

javascript

1import React, {Component} from 'react'; 2 3class Card extends Component { 4 constructor(props) { 5 super(props); 6 var urlPass = window.location.pathname 7 var uP = urlPass.slice(1) 8 console.log(uP) 9 this.state = {lang: uP} 10 console.log(this.state.lang) 11 } 12 13 componentDidMount() { 14 console.log(this.state.lang) 15 } 16 17 render() { 18 /*var urlPass = window.location.pathname 19 var uP = urlPass.slice(1) 20 console.log(uP)*/ 21 22 return( 23 <div>{this.state.lang}完全に理解した</div> 24 ); 25 } 26} 27 28export default Card;

constructor()を使っているので再びマウントされたら入れ替わるはずです。しかし、実際には起こっていません。App.jsRouteの問題なのか分かりません。

試したこと

render()内に書く

しかしこれは将来的にcomponentDidMount()内でURLパスを使い、APIの取得を考えているのでデータをcomponentDidMount()に渡せないのでやめました。

componentDidMount()内に書く

stateのセットがうまくできず空になり、またライフサイクルの都合上、DOMにも言語名が表示されませんでした。

なので、上記のコードでリンクを押すとコンポーネントを初期化し読み込んでくれる方法を教えてください!今のままでは入れ替えているはずが、同じCardコンポーネントとして処理され、URL遷移しか行われていない気がします。

追記

URL直叩きでも表示できるようにするため、遷移前のページからデータを渡すことは考えていません。

解決

ベストアンサーのようにRouteの使い方を正しくし、componentDidUpdateを併用したら解決しました。

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

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

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

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

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

guest

回答1

0

ベストアンサー

react-router の使い方が違います。そう書いても URL を query で受け取ることはできません。

diff

1- <Route path={'/' + this.state.query} component={Card} /> 2+ <Route path='/:lang' component={Card} />

これで Card で this.props.match.params.lang として受け取ることができるはずです。
参考: react-routerに入門する - Qiita


props が変わるので、state に設定する必要はなくて、単純に次の書き方じゃ駄目ですか?
(または componentWillReceiveProps で setState するか。)

js

1import React, {Component} from 'react'; 2 3class Card extends Component { 4 render() { 5 var urlPass = this.props.match.params.lang 6 7 return( 8 <div>{urlPass}完全に理解した</div> 9 ); 10 } 11} 12 13export default Card;

投稿2020/04/08 10:53

編集2020/04/08 12:31
hoshi-takanori

総合スコア7893

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

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

youj_biginner

2020/04/08 12:27 編集

回答ありがとうございます!回答していただいた通り、`App.js`を上記のように変え、`Card.js`を下記のようにしました。 ```javascript import React, {Component} from 'react'; class Card extends Component { constructor(props) { super(props); var urlPass = this.props.match.params.lang console.log(urlPass) this.state = {lang: urlPass} console.log(this.state.lang) } componentDidMount() { console.log(this.props.match.params.lang) } render() { return( <div>{this.props.match.params.lang}完全に理解した</div> ); } } export default Card; ``` 無事表示の面ではそれぞれ押すとそれぞれの言語が出るようになりました。しかし、出力を見ると最初pythonを押した時には無事出力されていましたが、そこから他の言語を押しても出力は何もされていません。これは他のリンクを押してもCardコンポーネントのままなのでコンポーネントは初期化されないということですか? 他の言語のリンクが押されるたびにcomponentDidMount()なども再び動かしたいのですが。
youj_biginner

2020/04/08 12:48

たびたびのご回答本当にありがとうございます。 そのようにしたらきちんと表示の面では動きました。ただ、そのURLパラメータを使い、将来的にはAPIをcomponentDidMount()で入手したいので、URL直叩きだけでなくリンクを押した時も再びcomponentDidMount()を動かしたいです。 しかし、今のままでは他の言語のリンクを押した時componentDidMount()は動いていません。そこの解決法が分からずじまいです。 何度も何度も質問して申し訳ございません。
youj_biginner

2020/04/08 13:13 編集

componentDidUpdateを使ったら解決しました!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問