🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

React.js

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

Q&A

解決済

1回答

889閲覧

配列の引数に変数を使って値を代入

nagisora

総合スコア0

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

React.js

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

0グッド

0クリップ

投稿2020/11/29 04:55

編集2020/11/29 08:19

前提・実現したいこと

・配列の引数に変数を使って値を代入したいです。
・最終的には、3x3の9マスのランダムな位置に、ランダムな数字を、1秒間隔で表示させ続けたいです。
・ReactチュートリアルをTypeScriptにしたものを参考にコーディングしています。
https://www.membersedge.co.jp/blog/refactor-react-official-tutorial/

発生している問題・エラーメッセージ

React

1Type '{ count: number; }' cannot be used as an index type. TS2538 2 3 40 | const interval = setInterval(() => { 4 41 | setCount(c => c + 1); 5 > 42 | squares[items[{count}].position] = items[{count}].value; 6 | ^ 7 43 | }, 1000); 8 44 | return () => clearInterval(interval); 9 45 | }, []);

該当のソースコード

React

1import React, { useState, useEffect } from 'react'; 2import './Borad.css'; 3import Square from './Square'; 4 5const Borad: React.FC = () => { 6 const [count, setCount] = useState(0); 7 8 var squares = [0,0,0,0,0,0,0,0,0]; 9 10 const items = [ 11 {position: 0, value: 2}, 12 {position: 1, value: 2}, 13 {position: 2, value: 2}, 14 {position: 3, value: 2}, 15 {position: 4, value: 2}, 16 {position: 5, value: 2}, 17 {position: 6, value: 2}, 18 {position: 7, value: 2}, 19 {position: 8, value: 2}, 20 ] 21 22 squares[items[2].position] = items[2].value; 23 24 useEffect(() => { 25 const interval = setInterval(() => { 26 setCount(c => c + 1); 27 squares[items[{count}].position] = items[{count}].value; 28 }, 1000); 29 return () => clearInterval(interval); 30 }, []); 31 32 return( 33 <> 34 {count}<br/><br/> 35 <div> 36 {[...Array(3)].map((_, i) => { 37 return ( 38 <div className="board-row" key={i}> 39 {[...Array(3)].map((_, j) => { 40 const index = 3 * i + j; 41 return ( 42 <Square 43 value={squares[index]} 44 key={j} 45 /> 46 ); 47 })} 48 </div> 49 ); 50 })} 51 </div> 52 </> 53 ) 54}; 55 56export default Borad;

試したこと

・変数ではなく値を直接入れた場合は、問題なく動作します。
・具体的には、22行目の以下の箇所です。
squares[items[2].position] = items[2].value;

補足情報(FW/ツールのバージョンなど)

package.json

1{ 2 "name": "my-app", 3 "version": "0.1.0", 4 "private": true, 5 "dependencies": { 6 "@testing-library/jest-dom": "^5.11.4", 7 "@testing-library/react": "^11.1.0", 8 "@testing-library/user-event": "^12.1.10", 9 "@types/jest": "^26.0.15", 10 "@types/node": "^12.0.0", 11 "@types/react": "^16.9.53", 12 "@types/react-dom": "^16.9.8", 13 "react": "^17.0.1", 14 "react-dom": "^17.0.1", 15 "react-scripts": "4.0.1", 16 "typescript": "^4.1.2", 17 "web-vitals": "^0.2.4" 18 }, 19 "scripts": { 20 "start": "react-scripts start", 21 "build": "react-scripts build", 22 "test": "react-scripts test", 23 "eject": "react-scripts eject" 24 }, 25 "eslintConfig": { 26 "extends": [ 27 "react-app", 28 "react-app/jest" 29 ] 30 }, 31 "browserslist": { 32 "production": [ 33 ">0.2%", 34 "not dead", 35 "not op_mini all" 36 ], 37 "development": [ 38 "last 1 chrome version", 39 "last 1 firefox version", 40 "last 1 safari version" 41 ] 42 } 43}

追記:{count}の括弧{}を外した場合

◆修正後のコード

useEffect(() => { const interval = setInterval(() => { setCount(c => c + 1); squares[items[count].position] = items[count].value; }, 1000); return () => clearInterval(interval); }, []);

◆エラー内容
・コンソール

Compiled with warnings. src/components/Borad.tsx Line 30:6: React Hook useEffect has missing dependencies: 'count', 'items', and 'squares'. Either include them or remove the dependency array react-hooks/exhaustive-deps Search for the keywords to learn more about each warning. To ignore, add // eslint-disable-next-line to the line before.

http://localhost:3000の表示

TypeError: Cannot read property 'position' of undefined (anonymous function) src/components/Borad.tsx:27 24 | useEffect(() => { 25 | const interval = setInterval(() => { 26 | setCount(c => c + 1); > 27 | squares[items[count].position] = items[count].value; | ^ 28 | }, 1000); 29 | return () => clearInterval(interval); 30 | }, []);

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

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

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

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

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

papinianus

2020/11/29 07:33

count の変数の前後にある波括弧{}を消して実行した結果を共有してくださいますか?
nagisora

2020/11/29 08:18

対応しようとしてくださりありがとうござます。 本文に追記させていただきました。 昔、私はC言語をやっていて、その感覚でreactに望んでいるので、変数と関数コンポーネントが頭の中でこんがらがっています汗
guest

回答1

0

自己解決

コードを弄りまくっていたら自己解決したので共有させていただきます。
上手く行った理由はわかりませんが、原因を下に列挙します。

皆様色々と考えてくださりありがとうございました。
もしよろしければ、何が悪かったのかを指摘していただけますと嬉しいです。

###原因?
・setStateが良く分からないため、変数でまず試そうとした。
・itemsをuseEffectの外に書いていた。
・useEffectを2個に分けないと駄目だった。

###修正後のコード

import React, { useState, useEffect } from 'react'; import './Borad.css'; import Square from './Square'; const Borad: React.FC = () => { const [count, setCount] = useState(0); const [squares, setSquares] = useState(Array(9).fill(0)); useEffect(() => { const interval = setInterval(() => { setCount(c => c + 1); }, 1000); return () => clearInterval(interval); }, []); useEffect(() => { const interval = setInterval(() => { const items = [ {position: 5, value: 3}, {position: 1, value: 5}, {position: 0, value: 4}, {position: 3, value: 8}, {position: 2, value: 6}, {position: 4, value: 9}, {position: 6, value: 2}, {position: 0, value: 1}, {position: 8, value: 7}, {position: 2, value: 3}, {position: 6, value: 5}, {position: 8, value: 4}, {position: 5, value: 8}, {position: 0, value: 6}, {position: 2, value: 9}, {position: 5, value: 2}, {position: 1, value: 1}, {position: 7, value: 7}, ] const newSquares = squares.slice() newSquares[items[count].position] = items[count].value; setSquares(newSquares) }, 1000); return () => clearInterval(interval); }, [squares]); return( <> {count}<br/><br/> <div> {[...Array(3)].map((_, i) => { return ( <div className="board-row" key={i}> {[...Array(3)].map((_, j) => { const index = 3 * i + j; return ( <Square value={squares[index]} key={j} /> ); })} </div> ); })} </div> </> ) }; export default Borad;

投稿2020/11/29 13:49

編集2020/11/29 14:02
nagisora

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問