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

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

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

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

React.js

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

Q&A

解決済

2回答

1671閲覧

React 配列に入った文字列を順番に表示したいです

wannabe

総合スコア5

JavaScript

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

React.js

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

0グッド

0クリップ

投稿2020/05/27 08:12

編集2020/05/27 08:28

前提・実現したいこと

配列に文字列が入っていて、その要素を一つずつ順番に表示したいです。
全て表示ではなく、イメージとしてはフラッシュ暗算のような感じになります。

Reactで時計を作るみたいにsetInterval等で簡単にできると思ったのですが、上手くできず困っております。

ちなみに、下のコードだと順番に表示はされるのですが三つ目くらいから挙動がおかしくなり、useEffectの部分が何度も高速で繰り返されるようになります(個人的にはライフサイクルメソッドに対する理解が浅いのだと思っています…)。

配列の要素を順番にログ出力することはできるのですが、表示となるとrederが関連してきてできなくなります。

該当のソースコード

javascript

1import React from 'react' 2import './App.css' 3 4const App = () => { 5 const words = [ 6 '私の', 7 '名前は', 8 '鈴木太郎', 9 'です。', 10 'よろしくお願いします。' 11 ] 12 const [count, setCount] = React.useState(0) 13 React.useEffect(() => { 14 setInterval(() => { 15 setCount(count + 1) 16 }, 1000) 17 }, [count, setCount]) 18 19 return ( 20 <div className="App"> 21 {words[count]} 22 </div> 23 ) 24} 25 26export default App 27

試したこと

その他には、setTimeoutを使ったり、メソッドを直接returnの中で呼び出したりしましたが、上記と同じような結果になってしまいました。

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

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

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

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

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

guest

回答2

0

このコードだと、一度setIntervalしたものは外れませんので、countが切り替わるたびにsetInterval増えることになります。

javascript

1 React.useEffect(() => { 2 const timer = setInterval(() => { 3 setCount(count => count + 1) 4 }, 1000) 5 return () => clearInterval(timer); 6 }, [setCount])

このように、useEffectの関数の返り値としてclearIntervalを行う関数を渡しましょう。なお、別件ですがsetCountも関数引数のほうがいいので、そのように書き換えています。

投稿2020/05/27 08:36

編集2020/05/27 08:37
maisumakun

総合スコア146018

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

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

wannabe

2020/05/27 08:41

回答ありがとうございます! ちょうど同じタイミングで自分なりに解決方法を見つけてしまいました。 setIntervalをclearしないといけないのですね。初めてまともに使う関数で十分に理解できていませんでした。ありがとうございます!
guest

0

自己解決

javascript

1import React from 'react' 2import './App.css' 3 4const App = () => { 5 const words = [ 6 '私の', 7 '名前は', 8 '鈴木太郎', 9 'です。', 10 'よろしくお願いします。' 11 ] 12 const [word, setWord] = React.useState('') 13 let index = 0 14 const wordCount = words.length 15 React.useEffect(() => { 16 setInterval(() => { 17 setWord(words[index++]) 18 }, 500) 19 }, [setWord, index]) 20 21 return ( 22 <div className="App"> 23 {word} 24 </div> 25 ) 26} 27 28export default App

こちらのコードで無事、思っていた通りに表示されました。
ありがとうございました。

投稿2020/05/27 08:37

wannabe

総合スコア5

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

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

maisumakun

2020/05/27 08:43

このコードだと「たまたま動いているだけ」というところです。 なにかの拍子にコンポーネント全体の再描画が入ると、indexが複数になってわけのわからない動作に陥ることが考えられます。
wannabe

2020/05/27 12:29

そういうことになってしまうのですね…。 setIntervalをしたらすぐにクリアしてあげる必要があるのですね。 アドバイスありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問